idf_build_apps 1.0.0.dev0__tar.gz → 1.0.0.dev1__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 (51) hide show
  1. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/CHANGELOG.md +12 -17
  2. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/PKG-INFO +1 -1
  3. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/__init__.py +1 -1
  4. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/app.py +97 -6
  5. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/finder.py +12 -24
  6. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/main.py +13 -12
  7. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/setup.py +1 -1
  8. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/tests/test_build.py +7 -13
  9. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/tests/test_finder.py +40 -6
  10. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.editorconfig +0 -0
  11. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.git-blame-ignore-revs +0 -0
  12. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.gitattributes +0 -0
  13. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/check-pre-commit.yml +0 -0
  14. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/issue_comment.yml +0 -0
  15. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/new_issues.yml +0 -0
  16. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/new_prs.yml +0 -0
  17. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/publish-pypi.yml +0 -0
  18. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/test-build-docs.yml +0 -0
  19. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.github/workflows/test-build-idf-apps.yml +0 -0
  20. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.gitignore +0 -0
  21. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.pre-commit-config.yaml +0 -0
  22. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/.readthedocs.yml +0 -0
  23. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/CONTRIBUTING.md +0 -0
  24. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/LICENSE +0 -0
  25. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/README.md +0 -0
  26. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/CHANGELOG.md +0 -0
  27. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/CONTRIBUTING.md +0 -0
  28. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/Makefile +0 -0
  29. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/_static/espressif-logo.svg +0 -0
  30. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/_static/theme_overrides.css +0 -0
  31. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/_templates/layout.html +0 -0
  32. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/api.rst +0 -0
  33. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/conf.py +0 -0
  34. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/config_file.md +0 -0
  35. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/find_build.md +0 -0
  36. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/index.rst +0 -0
  37. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/docs/manifest.md +0 -0
  38. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/__main__.py +0 -0
  39. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/config.py +0 -0
  40. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/constants.py +0 -0
  41. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/log.py +0 -0
  42. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/manifest/__init__.py +0 -0
  43. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/manifest/if_parser.py +0 -0
  44. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/manifest/manifest.py +0 -0
  45. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/manifest/soc_header.py +0 -0
  46. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/idf_build_apps/utils.py +0 -0
  47. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/license_header.txt +0 -0
  48. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/pyproject.toml +0 -0
  49. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/tests/conftest.py +0 -0
  50. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/tests/test_manifest.py +0 -0
  51. {idf_build_apps-1.0.0.dev0 → idf_build_apps-1.0.0.dev1}/tests/test_utils.py +0 -0
@@ -6,28 +6,23 @@ All notable changes to this project will be documented in this file.
6
6
 
7
7
  ## Added
8
8
 
9
- - Support keyword `depends_filepatterns` in the manfiest file
9
+ - Support keyword `depends_filepatterns` in the manifest file
10
10
 
11
11
  ## BREAKING CHANGES
12
12
 
13
- - Renames
14
- - Members
15
- - `App.requires_components` renamed to `App.depends_components`
16
- - `FolderRule.requires_components` renamed to `FolderRule.depends_components`
17
- - `Manifest.requires_components()` renamed to `Manifest.depends_components()`
18
- - Parameters
19
- - `App.build()` parameter `depends_on_components` renamed to `modified_components`
20
- - `App.is_modified()` parameter `depends_on_components` renamed to `modified_components`
21
- - `find_apps()` parameter `depends_on_components` renamed to `modified_components`
22
- - `find_apps()` parameter `depends_on_files` renamed to `modified_files`
23
- - `build_apps()` parameter `depends_on_components` renamed to `modified_components`
24
- - `build_apps()` parameter `depends_on_files` renamed to `modified_files`
25
- - CLI Options
26
- - `--depends-on-components` renamed to `--modified-components`
27
- - `--depends-on-files` renamed to `--modified-files`
28
- - Reorder Parameters
13
+ - Attributes Renamed
14
+ - `App.requires_components` renamed to `App.depends_components`
15
+ - `FolderRule.requires_components` renamed to `FolderRule.depends_components`
16
+ - Functions Renamed
17
+ - `Manifest.requires_components()` renamed to `Manifest.depends_components()`
18
+ - Signatures Changed
19
+ - `App.build()`
20
+ - `App.is_modified()`
29
21
  - `find_apps()`
30
22
  - `build_apps()`
23
+ - CLI Options Renamed
24
+ - `--depends-on-components` renamed to `--modified-components`
25
+ - `--depends-on-files` renamed to `--modified-files`
31
26
 
32
27
  ## [0.6.1] (2023-05-10)
33
28
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: idf-build-apps
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev1
4
4
  Summary: Tools for building ESP-IDF related apps.
5
5
  Author-email: Fu Hanxi <fuhanxi@espressif.com>
6
6
  Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
@@ -7,7 +7,7 @@ Tools for building ESP-IDF related apps.
7
7
 
8
8
  import logging
9
9
 
10
- __version__ = '1.0.0.dev0'
10
+ __version__ = '1.0.0.dev1'
11
11
 
12
12
  LOGGER = logging.getLogger('idf_build_apps')
13
13
 
@@ -37,6 +37,7 @@ from .manifest.manifest import (
37
37
  )
38
38
  from .utils import (
39
39
  BuildError,
40
+ files_matches_patterns,
40
41
  find_first_match,
41
42
  rmdir,
42
43
  subprocess_run,
@@ -50,6 +51,12 @@ except ImportError:
50
51
  pass
51
52
 
52
53
 
54
+ class BuildOrNot:
55
+ YES = 'yes'
56
+ NO = 'no'
57
+ UNKNOWN = 'unknown'
58
+
59
+
53
60
  class App(object):
54
61
  TARGET_PLACEHOLDER = '@t' # replace it with self.target
55
62
  WILDCARD_PLACEHOLDER = '@w' # replace it with the wildcard, usually the sdkconfig
@@ -101,6 +108,10 @@ class App(object):
101
108
  self.check_warnings = check_warnings
102
109
  self.preserve = preserve
103
110
 
111
+ # should be built or not
112
+ self.should_build = BuildOrNot.UNKNOWN
113
+ self._checked_should_build = False
114
+
104
115
  # Some miscellaneous build properties which are set later, at the build stage
105
116
  self.dry_run = False
106
117
  self.index = None
@@ -391,9 +402,10 @@ class App(object):
391
402
  @abstractmethod
392
403
  def build(
393
404
  self,
405
+ manifest_rootpath=None, # type: str | None
394
406
  modified_components=None, # type: list[str] | str | None
395
- check_component_dependencies=False, # type: bool
396
- is_modified=False, # type: bool
407
+ modified_files=None, # type: list[str] | str | None
408
+ check_app_dependencies=False, # type: bool
397
409
  ): # type: (...) -> bool
398
410
  pass
399
411
 
@@ -469,6 +481,68 @@ class App(object):
469
481
 
470
482
  return False
471
483
 
484
+ def check_should_build(
485
+ self,
486
+ manifest_rootpath, # type: str
487
+ check_app_dependencies, # type: bool
488
+ modified_components, # type: list[str] | None
489
+ modified_files, # type: list[str] | None
490
+ ): # type: (...) -> None
491
+ if self.should_build != BuildOrNot.UNKNOWN:
492
+ return
493
+
494
+ if not check_app_dependencies:
495
+ self.should_build = BuildOrNot.YES
496
+ self._checked_should_build = True
497
+ return
498
+
499
+ if self.is_modified(modified_files):
500
+ self.should_build = BuildOrNot.YES
501
+ self._checked_should_build = True
502
+ return
503
+
504
+ # check app dependencies
505
+ modified_components = to_list(modified_components)
506
+ modified_files = to_list(modified_files)
507
+
508
+ _modified_components = BuildOrNot.UNKNOWN
509
+ _modified_files = BuildOrNot.UNKNOWN
510
+
511
+ # depends components?
512
+ if check_app_dependencies and modified_components is not None:
513
+ if set(self.depends_components).intersection(set(modified_components)):
514
+ LOGGER.debug(
515
+ '=> Should be built. %s requires components: %s, modified components %s',
516
+ self,
517
+ ', '.join(self.depends_components),
518
+ ', '.join(modified_components),
519
+ )
520
+ _modified_components = BuildOrNot.YES
521
+ # if not defined dependency, we left it unknown and decide with idf.py reconfigure
522
+ elif self.depends_components:
523
+ _modified_components = BuildOrNot.NO
524
+
525
+ # or depends file patterns?
526
+ if check_app_dependencies and modified_files is not None:
527
+ if files_matches_patterns(modified_files, self.depends_filepatterns, manifest_rootpath):
528
+ LOGGER.debug(
529
+ '=> Should be built. %s depends on file patterns: %s, modified files %s',
530
+ self,
531
+ ', '.join(self.depends_filepatterns),
532
+ ', '.join(modified_files),
533
+ )
534
+ _modified_files = BuildOrNot.YES
535
+ # if not defined dependency, we left it unknown and decide with idf.py reconfigure
536
+ elif self.depends_filepatterns:
537
+ _modified_files = BuildOrNot.NO
538
+
539
+ if _modified_components == BuildOrNot.YES or _modified_files == BuildOrNot.YES:
540
+ self.should_build = BuildOrNot.YES
541
+ elif _modified_components == BuildOrNot.NO or _modified_files == BuildOrNot.NO:
542
+ self.should_build = BuildOrNot.NO
543
+
544
+ self._checked_should_build = True
545
+
472
546
 
473
547
  class CMakeApp(App):
474
548
  BUILD_SYSTEM = 'cmake'
@@ -493,10 +567,14 @@ class CMakeApp(App):
493
567
 
494
568
  def build(
495
569
  self,
570
+ manifest_rootpath=None, # type: str | None
496
571
  modified_components=None, # type: list[str] | str | None
497
- check_component_dependencies=False, # type: bool
498
- is_modified=False, # type: bool
572
+ modified_files=None, # type: list[str] | str | None
573
+ check_app_dependencies=False, # type: bool
499
574
  ): # type: (...) -> bool
575
+ modified_components = to_list(modified_components)
576
+ modified_files = to_list(modified_files)
577
+
500
578
  LOGGER.debug('=> Preparing...')
501
579
  if self.work_dir != self.app_dir:
502
580
  if os.path.exists(self.work_dir):
@@ -554,8 +632,15 @@ class CMakeApp(App):
554
632
  '-DSDKCONFIG_DEFAULTS={}'.format(';'.join(self.sdkconfig_files) if self.sdkconfig_files else ';'),
555
633
  ]
556
634
 
557
- modified_components = to_list(modified_components)
558
- if modified_components is not None and check_component_dependencies and not is_modified:
635
+ if not self._checked_should_build:
636
+ self.check_should_build(
637
+ manifest_rootpath=manifest_rootpath,
638
+ modified_components=modified_components,
639
+ modified_files=modified_files,
640
+ check_app_dependencies=check_app_dependencies,
641
+ )
642
+
643
+ if modified_components is not None and check_app_dependencies and self.should_build == BuildOrNot.UNKNOWN:
559
644
  subprocess_run(
560
645
  common_args + ['reconfigure'],
561
646
  log_terminal=False if self.build_log_path else True,
@@ -575,6 +660,12 @@ class CMakeApp(App):
575
660
  modified_components,
576
661
  )
577
662
  return False
663
+ else:
664
+ self.should_build = BuildOrNot.YES
665
+
666
+ if self.should_build == BuildOrNot.NO:
667
+ LOGGER.info('=> Skip building...')
668
+ return False
578
669
 
579
670
  # idf.py build
580
671
  build_args = deepcopy(common_args)
@@ -12,11 +12,11 @@ from . import (
12
12
  )
13
13
  from .app import (
14
14
  App,
15
+ BuildOrNot,
15
16
  CMakeApp,
16
17
  )
17
18
  from .utils import (
18
19
  config_rules_from_str,
19
- files_matches_patterns,
20
20
  to_list,
21
21
  )
22
22
 
@@ -35,7 +35,7 @@ def _get_apps_from_path(
35
35
  manifest_rootpath=None, # type: str | None
36
36
  modified_components=None, # type: list[str] | str | None
37
37
  modified_files=None, # type: list[str] | str | None,
38
- check_component_dependencies=False, # type: bool
38
+ check_app_dependencies=False, # type: bool
39
39
  sdkconfig_defaults_str=None, # type: str | None
40
40
  ): # type: (...) -> list[App]
41
41
  modified_components = to_list(modified_components)
@@ -46,28 +46,16 @@ def _get_apps_from_path(
46
46
  LOGGER.debug('=> Skipping. %s only supports targets: %s', _app, ', '.join(_app.supported_targets))
47
47
  return False
48
48
 
49
- if _app.is_modified(modified_files):
50
- return True
51
-
52
- if _app.depends_components and check_component_dependencies:
53
- if not set(_app.depends_components).intersection(set(modified_components)):
54
- LOGGER.debug(
55
- '=> Skipping. %s requires components: %s, but you passed "--modified-components %s"',
56
- _app,
57
- ', '.join(_app.depends_components),
58
- ', '.join(modified_components),
59
- )
60
- return False
61
-
62
- if _app.depends_filepatterns and check_component_dependencies:
63
- if not files_matches_patterns(modified_files, _app.depends_filepatterns, manifest_rootpath):
64
- LOGGER.debug(
65
- '=> Skipping. %s depends on file patterns: %s, but you passed "--modified-files %s"',
66
- _app,
67
- ', '.join(_app.depends_filepatterns),
68
- ', '.join(modified_files),
69
- )
70
- return False
49
+ _app.check_should_build(
50
+ manifest_rootpath=manifest_rootpath,
51
+ modified_components=modified_components,
52
+ modified_files=modified_files,
53
+ check_app_dependencies=check_app_dependencies,
54
+ )
55
+
56
+ # for unknown ones, we keep them to the build stage to judge
57
+ if _app.should_build == BuildOrNot.NO:
58
+ return False
71
59
 
72
60
  return True
73
61
 
@@ -51,20 +51,20 @@ except ImportError:
51
51
  pass
52
52
 
53
53
 
54
- def _check_components_dependency(
54
+ def _check_app_dependency(
55
55
  manifest_rootpath, # type: str
56
56
  modified_components, # type: list[str] | None
57
57
  modified_files, # type: list[str] | None
58
58
  ignore_component_dependencies_file_patterns, # type: list[str] | None
59
59
  ): # type: (...) -> bool
60
- # not check since `--modified-components` is not passed
60
+ # not check since modified_components and modified_files are not passed
61
61
  if modified_components is None and modified_files is None:
62
62
  return False
63
63
 
64
- # not check since `--ignore-component-dependency-file-pattern` is passed and matched
64
+ # not check since ignore_component_dependencies_file_patterns is passed and matched
65
65
  if (
66
66
  ignore_component_dependencies_file_patterns
67
- and modified_files
67
+ and modified_files is not None
68
68
  and files_matches_patterns(modified_files, ignore_component_dependencies_file_patterns, manifest_rootpath)
69
69
  ):
70
70
  LOGGER.debug(
@@ -191,14 +191,14 @@ def find_apps(
191
191
  check_warnings=check_warnings,
192
192
  preserve=preserve,
193
193
  manifest_rootpath=manifest_rootpath,
194
+ check_app_dependencies=_check_app_dependency(
195
+ manifest_rootpath=manifest_rootpath,
196
+ modified_components=modified_components,
197
+ modified_files=modified_files,
198
+ ignore_component_dependencies_file_patterns=ignore_component_dependencies_file_patterns,
199
+ ),
194
200
  modified_components=modified_components,
195
201
  modified_files=modified_files,
196
- check_component_dependencies=_check_components_dependency(
197
- manifest_rootpath,
198
- modified_components,
199
- modified_files,
200
- ignore_component_dependencies_file_patterns,
201
- ),
202
202
  sdkconfig_defaults_str=sdkconfig_defaults,
203
203
  )
204
204
  )
@@ -348,11 +348,12 @@ def build_apps(
348
348
  is_built = False
349
349
  try:
350
350
  is_built = app.build(
351
+ manifest_rootpath=manifest_rootpath,
351
352
  modified_components=modified_components,
352
- check_component_dependencies=_check_components_dependency(
353
+ modified_files=modified_files,
354
+ check_app_dependencies=_check_app_dependency(
353
355
  manifest_rootpath, modified_components, modified_files, ignore_component_dependencies_file_patterns
354
356
  ),
355
- is_modified=app.is_modified(modified_files),
356
357
  )
357
358
  except BuildError as e:
358
359
  LOGGER.error(str(e))
@@ -26,7 +26,7 @@ entry_points = \
26
26
  {'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
27
27
 
28
28
  setup(name='idf-build-apps',
29
- version='1.0.0.dev0',
29
+ version='1.0.0.dev1',
30
30
  description='Tools for building ESP-IDF related apps.',
31
31
  author=None,
32
32
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -24,7 +24,7 @@ class TestBuild:
24
24
  assert 'Project build complete.' in captured.out
25
25
 
26
26
  @pytest.mark.parametrize(
27
- 'modified_components, check_component_dependencies, assert_build_done',
27
+ 'modified_components, check_app_dependencies, should_be_built',
28
28
  [
29
29
  (None, True, True),
30
30
  ([], True, False),
@@ -37,21 +37,15 @@ class TestBuild:
37
37
  ],
38
38
  )
39
39
  def test_build_with_modified_components(
40
- self, tmpdir, capsys, modified_components, check_component_dependencies, assert_build_done
40
+ self, tmpdir, capsys, modified_components, check_app_dependencies, should_be_built
41
41
  ):
42
42
  path = IDF_PATH / 'examples' / 'get-started' / 'hello_world'
43
43
 
44
- CMakeApp(str(path), 'esp32', work_dir=str(tmpdir / 'test')).build(
44
+ is_built = CMakeApp(str(path), 'esp32', work_dir=str(tmpdir / 'test')).build(
45
45
  modified_components=modified_components,
46
- check_component_dependencies=check_component_dependencies,
46
+ check_app_dependencies=check_app_dependencies,
47
47
  )
48
-
49
- captured = capsys.readouterr()
50
- assert 'Configuring done' in captured.out
51
- if assert_build_done:
52
- assert 'Project build complete.' in captured.out
53
- else:
54
- assert 'Project build complete.' not in captured.out
48
+ assert is_built == should_be_built
55
49
 
56
50
  @pytest.mark.parametrize(
57
51
  'modified_files, is_built',
@@ -74,8 +68,8 @@ class TestBuild:
74
68
  app = CMakeApp(test_dir, 'esp32')
75
69
  built = app.build(
76
70
  modified_components=[],
77
- check_component_dependencies=True,
78
- is_modified=app.is_modified(modified_files),
71
+ modified_files=modified_files,
72
+ check_app_dependencies=True,
79
73
  )
80
74
 
81
75
  assert built == is_built
@@ -111,7 +111,7 @@ get-started:
111
111
  (['soc', 'fake'], True),
112
112
  ],
113
113
  )
114
- def test_with_requires_and_modified_components(self, tmpdir, modified_components, could_find_apps):
114
+ def test_with_depends_and_modified_components(self, tmpdir, modified_components, could_find_apps):
115
115
  test_dir = str(IDF_PATH / 'examples')
116
116
  apps = find_apps(test_dir, 'esp32', recursive=True)
117
117
  assert apps
@@ -183,12 +183,13 @@ get-started:
183
183
  assert not filtered_apps
184
184
 
185
185
  @pytest.mark.parametrize(
186
- 'modified_files, could_find_apps',
186
+ 'modified_components, modified_files, could_find_apps',
187
187
  [
188
- ('/foo', True),
189
- (str(IDF_PATH / 'examples' / 'README.md'), False),
190
- ([str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
188
+ ([], '/foo', True),
189
+ ([], str(IDF_PATH / 'examples' / 'README.md'), False),
190
+ (None, [str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
191
191
  (
192
+ [],
192
193
  [
193
194
  str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md'),
194
195
  str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.c'),
@@ -197,7 +198,7 @@ get-started:
197
198
  ),
198
199
  ],
199
200
  )
200
- def test_with_depends_filepatterns(self, tmp_path, modified_files, could_find_apps):
201
+ def test_with_depends_filepatterns(self, tmp_path, modified_components, modified_files, could_find_apps):
201
202
  test_dir = str(IDF_PATH / 'examples' / 'get-started' / 'hello_world')
202
203
  apps = find_apps(test_dir, 'esp32', recursive=True)
203
204
  assert apps
@@ -220,6 +221,39 @@ get-started:
220
221
  recursive=True,
221
222
  manifest_rootpath=str(IDF_PATH),
222
223
  manifest_files=yaml_file,
224
+ modified_components=modified_components,
225
+ modified_files=modified_files,
226
+ )
227
+ if could_find_apps:
228
+ assert filtered_apps == apps
229
+ else:
230
+ assert not filtered_apps
231
+
232
+ @pytest.mark.parametrize(
233
+ 'modified_files, could_find_apps',
234
+ [
235
+ (None, True),
236
+ (str(IDF_PATH / 'examples' / 'README.md'), True),
237
+ ([str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
238
+ (
239
+ [
240
+ str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md'),
241
+ str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.c'),
242
+ ],
243
+ True,
244
+ ),
245
+ ([str(IDF_PATH / 'examples' / 'a.c')], True),
246
+ ],
247
+ )
248
+ def test_with_filepattern_but_calculate_component_later(self, modified_files, could_find_apps):
249
+ test_dir = str(IDF_PATH / 'examples' / 'get-started' / 'hello_world')
250
+ apps = find_apps(test_dir, 'esp32', recursive=True)
251
+ assert apps
252
+
253
+ filtered_apps = find_apps(
254
+ test_dir,
255
+ 'esp32',
256
+ recursive=True,
223
257
  modified_files=modified_files,
224
258
  )
225
259
  if could_find_apps: