idf-build-apps 2.6.2__tar.gz → 2.6.4__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 (70) hide show
  1. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.pre-commit-config.yaml +2 -2
  2. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/CHANGELOG.md +14 -0
  3. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/PKG-INFO +1 -1
  4. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/__init__.py +1 -1
  5. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/app.py +6 -1
  6. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/args.py +2 -16
  7. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/main.py +10 -2
  8. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/utils.py +16 -2
  9. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/pyproject.toml +1 -1
  10. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/setup.py +1 -1
  11. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_app.py +18 -2
  12. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_build.py +17 -1
  13. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_finder.py +19 -1
  14. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.editorconfig +0 -0
  15. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.git-blame-ignore-revs +0 -0
  16. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.gitattributes +0 -0
  17. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/dependabot.yml +0 -0
  18. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/workflows/check-pre-commit.yml +0 -0
  19. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/workflows/publish-pypi.yml +0 -0
  20. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/workflows/sync-jira.yml +0 -0
  21. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/workflows/test-build-docs.yml +0 -0
  22. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.github/workflows/test-build-idf-apps.yml +0 -0
  23. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.gitignore +0 -0
  24. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/.readthedocs.yml +0 -0
  25. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/CONTRIBUTING.md +0 -0
  26. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/LICENSE +0 -0
  27. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/README.md +0 -0
  28. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_apidoc_templates/module.rst_t +0 -0
  29. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_apidoc_templates/package.rst_t +0 -0
  30. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_apidoc_templates/toc.rst_t +0 -0
  31. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_static/espressif-logo.svg +0 -0
  32. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_static/theme_overrides.css +0 -0
  33. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/_templates/layout.html +0 -0
  34. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/conf_common.py +0 -0
  35. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/Makefile +0 -0
  36. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/conf.py +0 -0
  37. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/explanations/build.rst +0 -0
  38. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/explanations/config_rules.rst +0 -0
  39. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/explanations/dependency_driven_build.rst +0 -0
  40. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/explanations/find.rst +0 -0
  41. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/guides/1.x_to_2.x.md +0 -0
  42. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/index.rst +0 -0
  43. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/others/CHANGELOG.md +0 -0
  44. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/others/CONTRIBUTING.md +0 -0
  45. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/references/cli.rst +0 -0
  46. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/references/config_file.rst +0 -0
  47. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/docs/en/references/manifest.rst +0 -0
  48. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/__main__.py +0 -0
  49. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/autocompletions.py +0 -0
  50. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/constants.py +0 -0
  51. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/finder.py +0 -0
  52. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/junit/__init__.py +0 -0
  53. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/junit/report.py +0 -0
  54. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/junit/utils.py +0 -0
  55. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/log.py +0 -0
  56. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/manifest/__init__.py +0 -0
  57. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/manifest/manifest.py +0 -0
  58. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/manifest/soc_header.py +0 -0
  59. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/py.typed +0 -0
  60. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/session_args.py +0 -0
  61. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/vendors/__init__.py +0 -0
  62. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/vendors/pydantic_sources.py +0 -0
  63. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/yaml/__init__.py +0 -0
  64. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/idf_build_apps/yaml/parser.py +0 -0
  65. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/license_header.txt +0 -0
  66. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/conftest.py +0 -0
  67. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_args.py +0 -0
  68. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_cmd.py +0 -0
  69. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_manifest.py +0 -0
  70. {idf_build_apps-2.6.2 → idf_build_apps-2.6.4}/tests/test_utils.py +0 -0
@@ -17,13 +17,13 @@ repos:
17
17
  - --use-current-year
18
18
  exclude: 'idf_build_apps/vendors/'
19
19
  - repo: https://github.com/charliermarsh/ruff-pre-commit
20
- rev: 'v0.8.4'
20
+ rev: 'v0.9.5'
21
21
  hooks:
22
22
  - id: ruff
23
23
  args: ['--fix']
24
24
  - id: ruff-format
25
25
  - repo: https://github.com/pre-commit/mirrors-mypy
26
- rev: 'v1.14.1'
26
+ rev: 'v1.15.0'
27
27
  hooks:
28
28
  - id: mypy
29
29
  args: ['--warn-unused-ignores']
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## v2.6.4 (2025-02-14)
6
+
7
+ ### Fix
8
+
9
+ - collect file not created when no apps built
10
+
11
+ ## v2.6.3 (2025-02-11)
12
+
13
+ ### Fix
14
+
15
+ - stop returning duplicated apps in `find_apps`
16
+ - compare app based on normalized paths
17
+ - remove unnecessary check args in dependency-driven-build
18
+
5
19
  ## v2.6.2 (2025-01-21)
6
20
 
7
21
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: idf-build-apps
3
- Version: 2.6.2
3
+ Version: 2.6.4
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
@@ -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.2'
11
+ __version__ = '2.6.4'
12
12
 
13
13
  from .session_args import (
14
14
  SessionArgs,
@@ -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
 
4
4
  import copy
@@ -127,6 +127,11 @@ class App(BaseModel):
127
127
  __EQ_IGNORE_FIELDS__ = [
128
128
  'build_comment',
129
129
  ]
130
+ __EQ_TUNE_FIELDS__ = {
131
+ 'app_dir': lambda x: (os.path.realpath(os.path.expanduser(x))),
132
+ 'work_dir': lambda x: (os.path.realpath(os.path.expanduser(x))),
133
+ 'build_dir': lambda x: (os.path.realpath(os.path.expanduser(x))),
134
+ }
130
135
 
131
136
  def __init__(
132
137
  self,
@@ -323,19 +323,6 @@ class DependencyDrivenBuildArguments(GlobalArguments):
323
323
  root_path=to_absolute_path(self.manifest_rootpath),
324
324
  )
325
325
 
326
- if self.deactivate_dependency_driven_build_by_components is not None:
327
- if self.modified_components is None:
328
- raise InvalidCommand(
329
- 'Must specify --deactivate-dependency-driven-build-by-components '
330
- 'together with --modified-components'
331
- )
332
-
333
- if self.deactivate_dependency_driven_build_by_filepatterns is not None:
334
- if self.modified_files is None:
335
- raise InvalidCommand(
336
- 'Must specify --deactivate-dependency-driven-build-by-filepatterns together with --modified-files'
337
- )
338
-
339
326
  @property
340
327
  def dependency_driven_build_enabled(self) -> bool:
341
328
  """
@@ -450,7 +437,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
450
437
  FieldMetadata(
451
438
  deprecates={'size_file': {}},
452
439
  ),
453
- description='`idf.py size` output file under the build directory when specified. ' 'Can expand placeholders',
440
+ description='`idf.py size` output file under the build directory when specified. Can expand placeholders',
454
441
  validation_alias=AliasChoices('size_json_filename', 'size_file'),
455
442
  default=None, # type: ignore
456
443
  )
@@ -654,8 +641,7 @@ class BuildArguments(FindBuildArguments):
654
641
  },
655
642
  nargs='+',
656
643
  ),
657
- description='space-separated list of patterns. '
658
- 'Ignore the warnings in the build output that match the patterns',
644
+ description='space-separated list of patterns. Ignore the warnings in the build output that match the patterns',
659
645
  validation_alias=AliasChoices('ignore_warning_strs', 'ignore_warning_str'),
660
646
  default=None, # type: ignore
661
647
  )
@@ -10,6 +10,7 @@ import os
10
10
  import sys
11
11
  import textwrap
12
12
  import typing as t
13
+ from pathlib import Path
13
14
 
14
15
  import argcomplete
15
16
  from pydantic import (
@@ -99,7 +100,7 @@ def find_apps(
99
100
  else:
100
101
  app_cls = find_arguments.build_system
101
102
 
102
- apps = []
103
+ apps: t.Set[App] = set()
103
104
  if find_arguments.target == 'all':
104
105
  targets = ALL_TARGETS
105
106
  else:
@@ -107,7 +108,7 @@ def find_apps(
107
108
 
108
109
  for _t in targets:
109
110
  for _p in find_arguments.paths:
110
- apps.extend(
111
+ apps.update(
111
112
  _find_apps(
112
113
  _p,
113
114
  _t,
@@ -170,6 +171,13 @@ def build_apps(
170
171
  LOGGER.debug('Remove existing collect file %s', f)
171
172
 
172
173
  exit_code = 0
174
+
175
+ # create empty files, avoid no file when no app is built
176
+ if build_arguments.collect_app_info:
177
+ Path(build_arguments.collect_app_info).touch()
178
+ if build_arguments.collect_size_info:
179
+ Path(build_arguments.collect_size_info).touch()
180
+
173
181
  for i, app in enumerate(apps):
174
182
  index = i + 1 # we use 1-based
175
183
  if index < start or index > stop:
@@ -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
 
4
4
  import fnmatch
@@ -340,6 +340,7 @@ class BaseModel(_BaseModel):
340
340
  """
341
341
 
342
342
  __EQ_IGNORE_FIELDS__: t.List[str] = []
343
+ __EQ_TUNE_FIELDS__: t.Dict[str, t.Callable[[t.Any], t.Any]] = {}
343
344
 
344
345
  def __lt__(self, other: t.Any) -> bool:
345
346
  if isinstance(other, self.__class__):
@@ -350,6 +351,10 @@ class BaseModel(_BaseModel):
350
351
  self_attr = getattr(self, k, '') or ''
351
352
  other_attr = getattr(other, k, '') or ''
352
353
 
354
+ if k in self.__EQ_TUNE_FIELDS__:
355
+ self_attr = str(self.__EQ_TUNE_FIELDS__[k](self_attr))
356
+ other_attr = str(self.__EQ_TUNE_FIELDS__[k](other_attr))
357
+
353
358
  if self_attr != other_attr:
354
359
  return self_attr < other_attr
355
360
 
@@ -369,13 +374,22 @@ class BaseModel(_BaseModel):
369
374
  self_model_dump.pop(_field, None)
370
375
  other_model_dump.pop(_field, None)
371
376
 
377
+ for _field in self.__EQ_TUNE_FIELDS__:
378
+ self_model_dump[_field] = self.__EQ_TUNE_FIELDS__[_field](self_model_dump[_field])
379
+ other_model_dump[_field] = self.__EQ_TUNE_FIELDS__[_field](other_model_dump[_field])
380
+
372
381
  return self_model_dump == other_model_dump
373
382
 
374
383
  return NotImplemented
375
384
 
376
385
  def __hash__(self) -> int:
377
386
  hash_list = []
378
- for v in self.model_dump().values():
387
+
388
+ self_model_dump = self.model_dump()
389
+ for _field in self.__EQ_TUNE_FIELDS__:
390
+ self_model_dump[_field] = self.__EQ_TUNE_FIELDS__[_field](self_model_dump[_field])
391
+
392
+ for v in self_model_dump.values():
379
393
  if isinstance(v, list):
380
394
  hash_list.append(tuple(v))
381
395
  elif isinstance(v, dict):
@@ -62,7 +62,7 @@ idf-build-apps = "idf_build_apps:main.main"
62
62
 
63
63
  [tool.commitizen]
64
64
  name = "cz_conventional_commits"
65
- version = "2.6.2"
65
+ version = "2.6.4"
66
66
  tag_format = "v$version"
67
67
  version_files = [
68
68
  "idf_build_apps/__init__.py",
@@ -37,7 +37,7 @@ entry_points = \
37
37
  {'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
38
38
 
39
39
  setup(name='idf-build-apps',
40
- version='2.6.2',
40
+ version='2.6.4',
41
41
  description='Tools for building ESP-IDF related apps.',
42
42
  author=None,
43
43
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -1,6 +1,7 @@
1
- # SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
-
3
+ import contextlib
4
+ import os
4
5
 
5
6
  import pytest
6
7
  from pydantic import (
@@ -95,3 +96,18 @@ def test_app_init_from_another():
95
96
  assert b.target == 'esp32c3'
96
97
  assert 'build_esp32_' == a.build_dir
97
98
  assert 'build_esp32c3_' == b.build_dir
99
+
100
+
101
+ def test_app_hash():
102
+ a = CMakeApp('foo', 'esp32')
103
+ b = CMakeApp('foo/', 'esp32')
104
+ assert a == b
105
+ assert hash(a) == hash(b)
106
+ assert len(list({a, b})) == 1
107
+
108
+ with contextlib.chdir(os.path.expanduser('~')):
109
+ a = CMakeApp('foo', 'esp32')
110
+ b = CMakeApp(os.path.join('~', 'foo'), 'esp32')
111
+ assert a == b
112
+ assert hash(a) == hash(b)
113
+ assert len(list({a, b})) == 1
@@ -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
 
4
4
  import os
@@ -22,6 +22,7 @@ from idf_build_apps import (
22
22
  from idf_build_apps.app import (
23
23
  CMakeApp,
24
24
  )
25
+ from idf_build_apps.args import BuildArguments
25
26
  from idf_build_apps.constants import (
26
27
  IDF_PATH,
27
28
  BuildStatus,
@@ -202,3 +203,18 @@ class TestBuild:
202
203
  assert test_suite.attrib['skipped'] == '0'
203
204
 
204
205
  assert test_suite.findall('testcase')[0].attrib['name'] == 'foo/bar/build'
206
+
207
+
208
+ def test_build_apps_collect_files_when_no_apps_built(tmp_path):
209
+ os.chdir(tmp_path)
210
+
211
+ build_apps(
212
+ build_arguments=BuildArguments(
213
+ target='esp32',
214
+ collect_app_info_filename='app_info.txt',
215
+ collect_size_info_filename='size_info.txt',
216
+ )
217
+ )
218
+
219
+ assert os.path.exists('app_info.txt')
220
+ assert os.path.exists('size_info.txt')
@@ -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
 
4
4
  import logging
@@ -740,3 +740,21 @@ def test_find_apps_with_exclude(tmp_path, exclude_list, apps_count):
740
740
  os.chdir(tempfile.tempdir)
741
741
  apps = find_apps(str(tmp_path), 'esp32', recursive=True, exclude_list=exclude_list)
742
742
  assert len(apps) == apps_count
743
+
744
+
745
+ def test_find_apps_with_duplicated_paths(tmp_path):
746
+ (tmp_path / 'folder1').mkdir()
747
+ create_project('test1', tmp_path / 'folder1')
748
+ create_project('test2', tmp_path / 'folder1')
749
+
750
+ assert (
751
+ len(
752
+ find_apps(
753
+ [str(tmp_path / 'folder1' / 'test1'), str(tmp_path / 'folder1')],
754
+ 'esp32',
755
+ recursive=True,
756
+ )
757
+ )
758
+ == len(find_apps(str(tmp_path / 'folder1'), 'esp32', recursive=True))
759
+ == 2
760
+ )
File without changes
File without changes