idf_build_apps 1.0.0__tar.gz → 1.0.0.dev0__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 → idf_build_apps-1.0.0.dev0}/.github/workflows/test-build-idf-apps.yml +3 -4
  2. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/CHANGELOG.md +19 -22
  3. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/PKG-INFO +1 -1
  4. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/find_build.md +1 -1
  5. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/manifest.md +6 -62
  6. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/__init__.py +1 -1
  7. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/app.py +6 -97
  8. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/finder.py +27 -19
  9. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/main.py +82 -48
  10. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/manifest/if_parser.py +0 -5
  11. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/utils.py +1 -1
  12. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/setup.py +1 -1
  13. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/tests/test_build.py +13 -24
  14. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/tests/test_finder.py +6 -122
  15. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.editorconfig +0 -0
  16. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.git-blame-ignore-revs +0 -0
  17. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.gitattributes +0 -0
  18. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/check-pre-commit.yml +0 -0
  19. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/issue_comment.yml +0 -0
  20. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/new_issues.yml +0 -0
  21. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/new_prs.yml +0 -0
  22. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/publish-pypi.yml +0 -0
  23. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.github/workflows/test-build-docs.yml +0 -0
  24. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.gitignore +0 -0
  25. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.pre-commit-config.yaml +0 -0
  26. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/.readthedocs.yml +0 -0
  27. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/CONTRIBUTING.md +0 -0
  28. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/LICENSE +0 -0
  29. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/README.md +0 -0
  30. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/CHANGELOG.md +0 -0
  31. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/CONTRIBUTING.md +0 -0
  32. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/Makefile +0 -0
  33. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/_static/espressif-logo.svg +0 -0
  34. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/_static/theme_overrides.css +0 -0
  35. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/_templates/layout.html +0 -0
  36. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/api.rst +0 -0
  37. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/conf.py +0 -0
  38. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/config_file.md +0 -0
  39. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/docs/index.rst +0 -0
  40. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/__main__.py +0 -0
  41. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/config.py +0 -0
  42. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/constants.py +0 -0
  43. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/log.py +0 -0
  44. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/manifest/__init__.py +0 -0
  45. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/manifest/manifest.py +0 -0
  46. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/idf_build_apps/manifest/soc_header.py +0 -0
  47. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/license_header.txt +0 -0
  48. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/pyproject.toml +0 -0
  49. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/tests/conftest.py +0 -0
  50. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/tests/test_manifest.py +0 -0
  51. {idf_build_apps-1.0.0 → idf_build_apps-1.0.0.dev0}/tests/test_utils.py +0 -0
@@ -66,10 +66,9 @@ jobs:
66
66
  python -m idf_build_apps build -vv -t esp32 \
67
67
  -p $IDF_PATH/examples/get-started/hello_world \
68
68
  --size-file size_info.json \
69
- --ignore-warning-str \
70
- "Python 3 versions older than 3.6 are not supported" \
71
- "Python 2 is no longer supported" \
72
- "Support for Python 2 is deprecated"
69
+ --ignore-warning-str "Python 3 versions older than 3.6 are not supported" \
70
+ --ignore-warning-str "Python 2 is no longer supported" \
71
+ --ignore-warning-str "Support for Python 2 is deprecated"
73
72
 
74
73
  build-apps-on-idf-env:
75
74
  if: ${{ github.ref == 'refs/heads/main' }}
@@ -2,35 +2,32 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [1.0.0] (2023-05-25)
5
+ ## [Unreleased - 1.0.0]
6
6
 
7
7
  ## Added
8
8
 
9
- - Support keyword `depends_filepatterns` in the manifest file
10
- - Support expanding environment variables in the manifest files
9
+ - Support keyword `depends_filepatterns` in the manfiest file
11
10
 
12
11
  ## BREAKING CHANGES
13
12
 
14
- - Attributes Renamed
15
- - `App.requires_components` renamed to `App.depends_components`
16
- - `FolderRule.requires_components` renamed to `FolderRule.depends_components`
17
- - Functions Renamed
18
- - `Manifest.requires_components()` renamed to `Manifest.depends_components()`
19
- - Signatures Changed
20
- - `App.build()`
21
- - `App.is_modified()`
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
22
29
  - `find_apps()`
23
30
  - `build_apps()`
24
- - CLI Options Renamed
25
- - `--depends-on-components` renamed to `--modified-components`
26
- - `--depends-on-files` renamed to `--modified-files`
27
- - `--ignore-components-dependencies-file-patterns` renamed to `--ignore-app-dependencies-filepatterns`
28
- - Removed the deprecated CLI call methods, now these options only support space-separated list
29
- - `--exclude`
30
- - `--config`
31
- - `--manifest-file`
32
- - `--ignore-warning-str`
33
- - `--default-build-targets`
34
31
 
35
32
  ## [0.6.1] (2023-05-10)
36
33
 
@@ -130,7 +127,7 @@ This is the last version to support ESP-IDF v4.1 since it's EOL on Feb. 24th, 20
130
127
 
131
128
  ### Fixed
132
129
 
133
- - Relative path defined in the manifest files depend on the current work path
130
+ - Ralative path defined in the manifest files depend on the current work path
134
131
 
135
132
  Added `manifest_rootpath` argument in `find_apps()`. Will use this value instead as the root folder for calculating absolute path
136
133
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: idf-build-apps
3
- Version: 1.0.0
3
+ Version: 1.0.0.dev0
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.*
@@ -114,7 +114,7 @@ By default, `idf-build-apps` would use the project directory as the work directo
114
114
 
115
115
  #### Build Directory
116
116
 
117
- Build directory is the directory where the binary files output would be generated. If it is set to a relative path, the full path would be calculated based on the work directory. If it is an absolute path, it would override the work directory settings.
117
+ Build directory is the directory where the binary files output would be generated. If it is set to a relative path, the full path would be calculated based on the work directory. If it is a absolute path, it would override the work directory settings.
118
118
 
119
119
  By default, `idf-build-apps` would follow what ESP-IDF does, use `build` as the build directory.
120
120
 
@@ -23,14 +23,12 @@ One typical manifest file look like this:
23
23
 
24
24
  ### Operands
25
25
 
26
- - Capitalized Words
27
- - Variables start with `SOC_`. The value would be parsed from `IDF_PATH/components/soc/[TARGET]/include/soc/*_caps.h`
28
- - `IDF_TARGET`
29
- - `IDF_VERSION_MAJOR`
30
- - `IDF_VERSION_MINOR`
31
- - `IDF_VERSION_PATCH`
32
- - `INCLUDE_DEFAULT` (The default value of officially supported targets is 1, otherwise is 0)
33
- - environment variables, default to `0` if not set
26
+ - Variables start with `SOC_`. The value would be parsed from `IDF_PATH/components/soc/[TARGET]/include/soc/*_caps.h`
27
+ - `IDF_TARGET`
28
+ - `IDF_VERSION_MAJOR`
29
+ - `IDF_VERSION_MINOR`
30
+ - `IDF_VERSION_PATCH`
31
+ - `INCLUDE_DEFAULT` (The default value of officially supported targets is 1, otherwise is 0)
34
32
  - String, must be double-quoted. e.g., `"esp32"`, `"12345"`
35
33
  - Integer, support decimal and hex. e.g., `1`, `0xAB`
36
34
  - List of strings or integers, or both types at the same time. e.g., `["esp32", 1]`
@@ -114,57 +112,3 @@ examples/get-started/blink:
114
112
  - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux"
115
113
  reason: This one supports all supported targets and linux
116
114
  ```
117
-
118
- ## Check App Dependencies
119
-
120
- `idf-build-apps` also supports building only related apps by checking app dependencies via modified components and modified files.
121
-
122
- ### Basic Usage
123
-
124
- To enable this feature, you need to declare the modified files or components using the CLI option:
125
-
126
- - `--modified-files`
127
- - `--modified-components`
128
-
129
- To declare the dependencies for an app, you could add two more keywords in the corresponding manifest file:
130
-
131
- - `depends_components`
132
- - `depends_filepatterns`
133
-
134
- One app will be built when:
135
-
136
- - The app itself is modified (`.md` files are excluded)
137
- - Any of the specified `depends_components` in the corresponding manifest file are modified
138
- - Files that matches any of the specified `depends_filepatterns` in the corresponding manifest file are modified
139
- - Any of the `build_components` are modified. `build_components` are defined in the `project_description.json`, which is generated by running `idf.py reconfigure` or `idf.py build`
140
-
141
- For example, this is an app `example/foo`, which depends on `comp1`, `comp2`, `comp3` and all files under `common_header_files`:
142
-
143
- ```yaml
144
- examples/foo:
145
- depends_components:
146
- - comp1
147
- - comp2
148
- - comp3
149
- depends_files:
150
- - "common_header_files/**/*"
151
- ```
152
-
153
- This app will be built with the following CLI options:
154
-
155
- - `--modified-files examples/foo/main/foo.c`
156
- - `--modified-components comp1`
157
- - `--modified-components comp2 comp3`
158
- - `--modified-files common_header_files/foo.h`
159
-
160
- This app will not be built with the following CLI options:
161
-
162
- - `--modified-files examples/foo/main/foo.md`
163
- - `--modified-components bar`
164
- - `/tmp/foo.c`
165
-
166
- ### Advanced Usage
167
-
168
- Sometimes, we have some root dependencies. All apps should be built if these root dependencies are modified.
169
-
170
- After adding `--ignore-app-dependencies-filepatterns` to the CLI options, if files that matches any of the specified patterns are modified, the check app dependency feature will be disabled.
@@ -7,7 +7,7 @@ Tools for building ESP-IDF related apps.
7
7
 
8
8
  import logging
9
9
 
10
- __version__ = '1.0.0'
10
+ __version__ = '1.0.0.dev0'
11
11
 
12
12
  LOGGER = logging.getLogger('idf_build_apps')
13
13
 
@@ -37,7 +37,6 @@ from .manifest.manifest import (
37
37
  )
38
38
  from .utils import (
39
39
  BuildError,
40
- files_matches_patterns,
41
40
  find_first_match,
42
41
  rmdir,
43
42
  subprocess_run,
@@ -51,12 +50,6 @@ except ImportError:
51
50
  pass
52
51
 
53
52
 
54
- class BuildOrNot:
55
- YES = 'yes'
56
- NO = 'no'
57
- UNKNOWN = 'unknown'
58
-
59
-
60
53
  class App(object):
61
54
  TARGET_PLACEHOLDER = '@t' # replace it with self.target
62
55
  WILDCARD_PLACEHOLDER = '@w' # replace it with the wildcard, usually the sdkconfig
@@ -108,10 +101,6 @@ class App(object):
108
101
  self.check_warnings = check_warnings
109
102
  self.preserve = preserve
110
103
 
111
- # should be built or not
112
- self.should_build = BuildOrNot.UNKNOWN
113
- self._checked_should_build = False
114
-
115
104
  # Some miscellaneous build properties which are set later, at the build stage
116
105
  self.dry_run = False
117
106
  self.index = None
@@ -402,10 +391,9 @@ class App(object):
402
391
  @abstractmethod
403
392
  def build(
404
393
  self,
405
- manifest_rootpath=None, # type: str | None
406
394
  modified_components=None, # type: list[str] | str | None
407
- modified_files=None, # type: list[str] | str | None
408
- check_app_dependencies=False, # type: bool
395
+ check_component_dependencies=False, # type: bool
396
+ is_modified=False, # type: bool
409
397
  ): # type: (...) -> bool
410
398
  pass
411
399
 
@@ -481,68 +469,6 @@ class App(object):
481
469
 
482
470
  return False
483
471
 
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
-
546
472
 
547
473
  class CMakeApp(App):
548
474
  BUILD_SYSTEM = 'cmake'
@@ -567,14 +493,10 @@ class CMakeApp(App):
567
493
 
568
494
  def build(
569
495
  self,
570
- manifest_rootpath=None, # type: str | None
571
496
  modified_components=None, # type: list[str] | str | None
572
- modified_files=None, # type: list[str] | str | None
573
- check_app_dependencies=False, # type: bool
497
+ check_component_dependencies=False, # type: bool
498
+ is_modified=False, # type: bool
574
499
  ): # type: (...) -> bool
575
- modified_components = to_list(modified_components)
576
- modified_files = to_list(modified_files)
577
-
578
500
  LOGGER.debug('=> Preparing...')
579
501
  if self.work_dir != self.app_dir:
580
502
  if os.path.exists(self.work_dir):
@@ -632,15 +554,8 @@ class CMakeApp(App):
632
554
  '-DSDKCONFIG_DEFAULTS={}'.format(';'.join(self.sdkconfig_files) if self.sdkconfig_files else ';'),
633
555
  ]
634
556
 
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:
557
+ modified_components = to_list(modified_components)
558
+ if modified_components is not None and check_component_dependencies and not is_modified:
644
559
  subprocess_run(
645
560
  common_args + ['reconfigure'],
646
561
  log_terminal=False if self.build_log_path else True,
@@ -660,12 +575,6 @@ class CMakeApp(App):
660
575
  modified_components,
661
576
  )
662
577
  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
669
578
 
670
579
  # idf.py build
671
580
  build_args = deepcopy(common_args)
@@ -12,12 +12,11 @@ from . import (
12
12
  )
13
13
  from .app import (
14
14
  App,
15
- BuildOrNot,
16
15
  CMakeApp,
17
16
  )
18
17
  from .utils import (
19
18
  config_rules_from_str,
20
- to_absolute_path,
19
+ files_matches_patterns,
21
20
  to_list,
22
21
  )
23
22
 
@@ -36,7 +35,7 @@ def _get_apps_from_path(
36
35
  manifest_rootpath=None, # type: str | None
37
36
  modified_components=None, # type: list[str] | str | None
38
37
  modified_files=None, # type: list[str] | str | None,
39
- check_app_dependencies=False, # type: bool
38
+ check_component_dependencies=False, # type: bool
40
39
  sdkconfig_defaults_str=None, # type: str | None
41
40
  ): # type: (...) -> list[App]
42
41
  modified_components = to_list(modified_components)
@@ -47,16 +46,28 @@ def _get_apps_from_path(
47
46
  LOGGER.debug('=> Skipping. %s only supports targets: %s', _app, ', '.join(_app.supported_targets))
48
47
  return False
49
48
 
50
- _app.check_should_build(
51
- manifest_rootpath=manifest_rootpath,
52
- modified_components=modified_components,
53
- modified_files=modified_files,
54
- check_app_dependencies=check_app_dependencies,
55
- )
56
-
57
- # for unknown ones, we keep them to the build stage to judge
58
- if _app.should_build == BuildOrNot.NO:
59
- return False
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
60
71
 
61
72
  return True
62
73
 
@@ -166,18 +177,15 @@ def _find_apps(
166
177
 
167
178
  # The remaining part is for recursive == True
168
179
  apps = []
169
- # handle the exclude list, since the config file might use linux style, but run in windows
170
- exclude_list = [to_absolute_path(p) for p in exclude_list]
171
180
  for root, dirs, _ in os.walk(path):
172
181
  LOGGER.debug('Entering %s', root)
173
- root_path = to_absolute_path(root)
174
- if root_path in exclude_list:
182
+ if root in exclude_list:
175
183
  LOGGER.debug('=> Skipping %s (excluded)', root)
176
184
  del dirs[:]
177
185
  continue
178
186
 
179
- if root_path.parts[-1] == 'managed_components': # idf-component-manager
180
- LOGGER.debug('=> Skipping %s (managed components)', root_path)
187
+ if root.endswith('managed_components'): # idf-component-manager
188
+ LOGGER.debug('=> Skipping %s (managed components)', root)
181
189
  del dirs[:]
182
190
  continue
183
191
 
@@ -2,12 +2,14 @@
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import argparse
5
+ import io
5
6
  import json
6
7
  import os
7
8
  import re
8
9
  import shutil
9
10
  import sys
10
11
  import textwrap
12
+ import warnings
11
13
  from pathlib import (
12
14
  Path,
13
15
  )
@@ -49,26 +51,26 @@ except ImportError:
49
51
  pass
50
52
 
51
53
 
52
- def _check_app_dependency(
54
+ def _check_components_dependency(
53
55
  manifest_rootpath, # type: str
54
56
  modified_components, # type: list[str] | None
55
57
  modified_files, # type: list[str] | None
56
- ignore_app_dependencies_filepatterns, # type: list[str] | None
58
+ ignore_component_dependencies_file_patterns, # type: list[str] | None
57
59
  ): # type: (...) -> bool
58
- # not check since modified_components and modified_files are not passed
60
+ # not check since `--modified-components` is not passed
59
61
  if modified_components is None and modified_files is None:
60
62
  return False
61
63
 
62
- # not check since ignore_app_dependencies_filepatterns is passed and matched
64
+ # not check since `--ignore-component-dependency-file-pattern` is passed and matched
63
65
  if (
64
- ignore_app_dependencies_filepatterns
65
- and modified_files is not None
66
- and files_matches_patterns(modified_files, ignore_app_dependencies_filepatterns, manifest_rootpath)
66
+ ignore_component_dependencies_file_patterns
67
+ and modified_files
68
+ and files_matches_patterns(modified_files, ignore_component_dependencies_file_patterns, manifest_rootpath)
67
69
  ):
68
70
  LOGGER.debug(
69
71
  'Skipping check component dependencies for apps since files %s matches patterns: %s',
70
72
  ', '.join(modified_files),
71
- ', '.join(ignore_app_dependencies_filepatterns),
73
+ ', '.join(ignore_component_dependencies_file_patterns),
72
74
  )
73
75
  return False
74
76
 
@@ -93,7 +95,7 @@ def find_apps(
93
95
  default_build_targets=None, # type: list[str] | str | None
94
96
  modified_components=None, # type: list[str] | str | None
95
97
  modified_files=None, # type: list[str] | str | None
96
- ignore_app_dependencies_filepatterns=None, # type: list[str] | str | None
98
+ ignore_component_dependencies_file_patterns=None, # type: list[str] | str | None
97
99
  sdkconfig_defaults=None, # type: str | None
98
100
  ): # type: (...) -> list[App]
99
101
  """
@@ -137,9 +139,9 @@ def find_apps(
137
139
  :type modified_components: list[str] | str | None
138
140
  :param modified_files: modified files
139
141
  :type modified_files: list[str] | str | None
140
- :param ignore_app_dependencies_filepatterns: file patterns that used for ignoring checking the component
142
+ :param ignore_component_dependencies_file_patterns: file patterns that used for ignoring checking the component
141
143
  dependencies
142
- :type ignore_app_dependencies_filepatterns: list[str] | str | None
144
+ :type ignore_component_dependencies_file_patterns: list[str] | str | None
143
145
  :param sdkconfig_defaults: semicolon-separated string, pass to idf.py -DSDKCONFIG_DEFAULTS if specified,
144
146
  also could be set via environment variables "SDKCONFIG_DEFAULTS"
145
147
  :type sdkconfig_defaults: str | None
@@ -164,7 +166,7 @@ def find_apps(
164
166
 
165
167
  modified_components = to_list(modified_components)
166
168
  modified_files = to_list(modified_files)
167
- ignore_app_dependencies_filepatterns = to_list(ignore_app_dependencies_filepatterns)
169
+ ignore_component_dependencies_file_patterns = to_list(ignore_component_dependencies_file_patterns)
168
170
 
169
171
  apps = []
170
172
  if target == 'all':
@@ -189,14 +191,14 @@ def find_apps(
189
191
  check_warnings=check_warnings,
190
192
  preserve=preserve,
191
193
  manifest_rootpath=manifest_rootpath,
192
- check_app_dependencies=_check_app_dependency(
193
- manifest_rootpath=manifest_rootpath,
194
- modified_components=modified_components,
195
- modified_files=modified_files,
196
- ignore_app_dependencies_filepatterns=ignore_app_dependencies_filepatterns,
197
- ),
198
194
  modified_components=modified_components,
199
195
  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
+ ),
200
202
  sdkconfig_defaults_str=sdkconfig_defaults,
201
203
  )
202
204
  )
@@ -221,7 +223,7 @@ def build_apps(
221
223
  manifest_rootpath=None, # type: str | None
222
224
  modified_components=None, # type: list[str] | str | None
223
225
  modified_files=None, # type: list[str] | str | None
224
- ignore_app_dependencies_filepatterns=None, # type: list[str] | str | None
226
+ ignore_component_dependencies_file_patterns=None, # type: list[str] | str | None
225
227
  ): # type: (...) -> (int, list[App]) | int
226
228
  """
227
229
  Build all the specified apps
@@ -256,9 +258,9 @@ def build_apps(
256
258
  :type modified_components: list[str] | str | None
257
259
  :param modified_files: modified files
258
260
  :type modified_files: list[str] | str | None
259
- :param ignore_app_dependencies_filepatterns: file patterns that used for ignoring checking the component
261
+ :param ignore_component_dependencies_file_patterns: file patterns that used for ignoring checking the component
260
262
  dependencies
261
- :type ignore_app_dependencies_filepatterns: list[str] | str | None
263
+ :type ignore_component_dependencies_file_patterns: list[str] | str | None
262
264
  :return: (exit_code, built_apps) if specified ``modified_components``
263
265
  :rtype: int, list[App]
264
266
  :return: exit_code if not specified ``modified_components``
@@ -267,7 +269,7 @@ def build_apps(
267
269
  apps = to_list(apps) # type: list[App]
268
270
  modified_components = to_list(modified_components)
269
271
  modified_files = to_list(modified_files)
270
- ignore_app_dependencies_filepatterns = to_list(ignore_app_dependencies_filepatterns)
272
+ ignore_component_dependencies_file_patterns = to_list(ignore_component_dependencies_file_patterns)
271
273
 
272
274
  ignore_warnings_regexes = []
273
275
  if ignore_warning_strs:
@@ -298,13 +300,27 @@ def build_apps(
298
300
  app.parallel_count = parallel_count
299
301
 
300
302
  if collect_app_info:
301
- app._collect_app_info = collect_app_info
303
+ if isinstance(collect_app_info, io.TextIOWrapper):
304
+ warnings.warn(
305
+ '"collect_app_info" does not support file stream in idf-build-apps 1.0.0, Please use str instead',
306
+ DeprecationWarning,
307
+ )
308
+ app._collect_app_info = collect_app_info.name
309
+ else:
310
+ app._collect_app_info = collect_app_info
302
311
 
303
312
  if app.collect_app_info not in collect_files:
304
313
  collect_files.append(app.collect_app_info)
305
314
 
306
315
  if collect_size_info:
307
- app._collect_size_info = collect_size_info
316
+ if isinstance(collect_size_info, io.TextIOWrapper):
317
+ warnings.warn(
318
+ '"collect_size_info" does not support file stream in idf-build-apps 1.0.0, Please use str instead',
319
+ DeprecationWarning,
320
+ )
321
+ app._collect_size_info = collect_size_info.name
322
+ else:
323
+ app._collect_size_info = collect_size_info
308
324
 
309
325
  if app.collect_size_info not in collect_files:
310
326
  collect_files.append(app.collect_size_info)
@@ -332,12 +348,11 @@ def build_apps(
332
348
  is_built = False
333
349
  try:
334
350
  is_built = app.build(
335
- manifest_rootpath=manifest_rootpath,
336
351
  modified_components=modified_components,
337
- modified_files=modified_files,
338
- check_app_dependencies=_check_app_dependency(
339
- manifest_rootpath, modified_components, modified_files, ignore_app_dependencies_filepatterns
352
+ check_component_dependencies=_check_components_dependency(
353
+ manifest_rootpath, modified_components, modified_files, ignore_component_dependencies_file_patterns
340
354
  ),
355
+ is_modified=app.is_modified(modified_files),
341
356
  )
342
357
  except BuildError as e:
343
358
  LOGGER.error(str(e))
@@ -452,7 +467,15 @@ class IdfBuildAppsCliFormatter(argparse.HelpFormatter):
452
467
  else:
453
468
  default_type = type(action.default)
454
469
 
455
- if action.nargs in [argparse.ZERO_OR_MORE, argparse.ONE_OR_MORE]:
470
+ if isinstance(action, argparse._AppendAction): # noqa
471
+ _help += (
472
+ '. Could be specified for multiple times'
473
+ '{} ! DeprecationWarning: will change to space-separated list in idf-build-apps 1.0.0 version'.format(
474
+ self.LINE_SEP
475
+ )
476
+ )
477
+ _type = 'list[{}]'.format(default_type.__name__)
478
+ elif action.nargs in [argparse.ZERO_OR_MORE, argparse.ONE_OR_MORE]:
456
479
  _type = 'list[{}]'.format(default_type.__name__)
457
480
  else:
458
481
  _type = default_type.__name__
@@ -498,7 +521,11 @@ def get_parser(): # type: () -> argparse.ArgumentParser
498
521
  action='store_true',
499
522
  help='Look for apps in the specified paths recursively',
500
523
  )
501
- common_args.add_argument('--exclude', nargs='+', help='Ignore specified path (if --recursive is given)')
524
+ common_args.add_argument(
525
+ '--exclude',
526
+ action='append',
527
+ help='Ignore specified directory (if --recursive is given)',
528
+ )
502
529
  common_args.add_argument(
503
530
  '--work-dir',
504
531
  help='If set, the app is first copied into the specified directory, and then built. '
@@ -520,7 +547,7 @@ def get_parser(): # type: () -> argparse.ArgumentParser
520
547
  )
521
548
  common_args.add_argument(
522
549
  '--config',
523
- nargs='+',
550
+ action='append',
524
551
  help='Adds configurations (sdkconfig file names) to build. '
525
552
  'This can either be FILENAME[=NAME] or FILEPATTERN. FILENAME is the name of the sdkconfig file, '
526
553
  'relative to the project directory, to be used. Optional NAME can be specified, '
@@ -550,7 +577,7 @@ def get_parser(): # type: () -> argparse.ArgumentParser
550
577
  )
551
578
  common_args.add_argument(
552
579
  '--manifest-file',
553
- nargs='+',
580
+ action='append',
554
581
  help='Manifest files which specify the build test rules of the apps',
555
582
  )
556
583
  common_args.add_argument(
@@ -562,7 +589,10 @@ def get_parser(): # type: () -> argparse.ArgumentParser
562
589
  '--default-build-targets',
563
590
  nargs='+',
564
591
  help='space-separated list of supported targets. Targets supported in current ESP-IDF branch '
565
- '(except preview ones) would be used if this option is not set.',
592
+ '(except preview ones) would be used if this option is not set.'
593
+ '{} ! DeprecationWarning: comma-separated list support will be removed in idf-build-apps 1.0.0 version'.format(
594
+ IdfBuildAppsCliFormatter.LINE_SEP
595
+ ),
566
596
  )
567
597
  common_args.add_argument(
568
598
  '--modified-components',
@@ -581,12 +611,13 @@ def get_parser(): # type: () -> argparse.ArgumentParser
581
611
  )
582
612
  common_args.add_argument(
583
613
  '-if',
584
- '--ignore-app-dependencies-filepatterns',
614
+ '--ignore-component-dependencies-file-patterns',
585
615
  nargs='*',
586
616
  default=None,
587
- help='space-separated list which specifies the file patterns used for ignoring checking the app dependencies. '
588
- 'The `depends_components` and `depends_filepatterns` set in the manifest files will be ignored when any of the '
589
- 'specified file patterns matches any of the modified files. Must be used together with --modified-files',
617
+ help='space-separated list which specifies the file patterns used for ignoring the component dependencies. '
618
+ 'The `depends_components` and `depends_filepatterns` set in the manifest files will be ignored when any of '
619
+ 'the specified file patterns matches any of the modified files. Must be used together with '
620
+ '--modified-files',
590
621
  )
591
622
 
592
623
  common_args.add_argument(
@@ -643,7 +674,7 @@ def get_parser(): # type: () -> argparse.ArgumentParser
643
674
  )
644
675
  build_parser.add_argument(
645
676
  '--ignore-warning-str',
646
- nargs='+',
677
+ action='append',
647
678
  help='Ignore the warning string that match the specified regex in the build output',
648
679
  )
649
680
  build_parser.add_argument(
@@ -680,17 +711,20 @@ def validate_args(parser, args): # type: (argparse.ArgumentParser, argparse.Nam
680
711
  default_build_targets = []
681
712
  if args.default_build_targets:
682
713
  for target in args.default_build_targets:
683
- if target not in ALL_TARGETS:
684
- raise InvalidCommand(
685
- 'Unrecognizable target {} specified with "--default-build-targets". '
686
- 'Current ESP-IDF available targets: {}'.format(target, ALL_TARGETS)
687
- )
714
+ t_list = [_t.strip() for _t in target.split(',')] if ',' in target else [target.strip()]
715
+ for _t in t_list:
716
+ if _t not in ALL_TARGETS:
717
+ raise InvalidCommand(
718
+ 'Unrecognizable target {} specified with "--default-build-targets". '
719
+ 'Current ESP-IDF available targets: {}'.format(_t, ALL_TARGETS)
720
+ )
721
+
722
+ if _t not in default_build_targets:
723
+ default_build_targets.append(_t)
688
724
 
689
- if target not in default_build_targets:
690
- default_build_targets.append(target)
691
725
  args.default_build_targets = default_build_targets
692
726
 
693
- if args.ignore_app_dependencies_filepatterns:
727
+ if args.ignore_component_dependencies_file_patterns:
694
728
  if args.modified_files is None:
695
729
  raise InvalidCommand(
696
730
  'Must specify "--ignore-component-dependencies-file-patterns" with "--modified-files", '
@@ -732,7 +766,7 @@ def main():
732
766
  default_build_targets=args.default_build_targets,
733
767
  modified_components=args.modified_components,
734
768
  modified_files=args.modified_files,
735
- ignore_app_dependencies_filepatterns=args.ignore_app_dependencies_filepatterns,
769
+ ignore_component_dependencies_file_patterns=args.ignore_component_dependencies_file_patterns,
736
770
  sdkconfig_defaults=args.sdkconfig_defaults,
737
771
  )
738
772
 
@@ -766,7 +800,7 @@ def main():
766
800
  manifest_rootpath=args.manifest_rootpath,
767
801
  modified_components=args.modified_components,
768
802
  modified_files=args.modified_files,
769
- ignore_app_dependencies_filepatterns=args.ignore_app_dependencies_filepatterns,
803
+ ignore_component_dependencies_file_patterns=args.ignore_component_dependencies_file_patterns,
770
804
  )
771
805
 
772
806
  if args.modified_components is not None:
@@ -1,7 +1,6 @@
1
1
  # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import os
5
4
  from ast import (
6
5
  literal_eval,
7
6
  )
@@ -87,10 +86,6 @@ class ChipAttr(Stmt):
87
86
  if self.attr in SOC_HEADERS[target]:
88
87
  return SOC_HEADERS[target][self.attr]
89
88
 
90
- # for non-keyword cap words, check if it is defined in the environment variables
91
- if self.attr in os.environ:
92
- return os.environ[self.attr]
93
-
94
89
  return 0 # default return 0 as false
95
90
 
96
91
 
@@ -213,7 +213,7 @@ def files_matches_patterns(
213
213
  patterns, # type: list[str] | str
214
214
  rootpath=None, # type: str
215
215
  ): # type: (...) -> bool
216
- # can't match an absolute pattern with a relative path
216
+ # can't match a absolute pattern with a relative path
217
217
  # change all to absolute paths
218
218
  files = [to_absolute_path(f, rootpath) for f in to_list(files)]
219
219
  patterns = [to_absolute_path(p, rootpath) for p in to_list(patterns)]
@@ -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',
29
+ version='1.0.0.dev0',
30
30
  description='Tools for building ESP-IDF related apps.',
31
31
  author=None,
32
32
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -4,9 +4,6 @@ import shutil
4
4
 
5
5
  import pytest
6
6
 
7
- from idf_build_apps import (
8
- find_apps,
9
- )
10
7
  from idf_build_apps.app import (
11
8
  CMakeApp,
12
9
  )
@@ -27,7 +24,7 @@ class TestBuild:
27
24
  assert 'Project build complete.' in captured.out
28
25
 
29
26
  @pytest.mark.parametrize(
30
- 'modified_components, check_app_dependencies, should_be_built',
27
+ 'modified_components, check_component_dependencies, assert_build_done',
31
28
  [
32
29
  (None, True, True),
33
30
  ([], True, False),
@@ -40,15 +37,21 @@ class TestBuild:
40
37
  ],
41
38
  )
42
39
  def test_build_with_modified_components(
43
- self, tmpdir, capsys, modified_components, check_app_dependencies, should_be_built
40
+ self, tmpdir, capsys, modified_components, check_component_dependencies, assert_build_done
44
41
  ):
45
42
  path = IDF_PATH / 'examples' / 'get-started' / 'hello_world'
46
43
 
47
- is_built = CMakeApp(str(path), 'esp32', work_dir=str(tmpdir / 'test')).build(
44
+ CMakeApp(str(path), 'esp32', work_dir=str(tmpdir / 'test')).build(
48
45
  modified_components=modified_components,
49
- check_app_dependencies=check_app_dependencies,
46
+ check_component_dependencies=check_component_dependencies,
50
47
  )
51
- assert is_built == should_be_built
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
52
55
 
53
56
  @pytest.mark.parametrize(
54
57
  'modified_files, is_built',
@@ -71,26 +74,12 @@ class TestBuild:
71
74
  app = CMakeApp(test_dir, 'esp32')
72
75
  built = app.build(
73
76
  modified_components=[],
74
- modified_files=modified_files,
75
- check_app_dependencies=True,
77
+ check_component_dependencies=True,
78
+ is_modified=app.is_modified(modified_files),
76
79
  )
77
80
 
78
81
  assert built == is_built
79
82
 
80
- def test_build_without_modified_components_but_ignored_app_dependency_check(self):
81
- test_dir = str(IDF_PATH / 'examples' / 'get-started' / 'hello_world')
82
-
83
- apps = find_apps(
84
- test_dir,
85
- 'esp32',
86
- modified_components=[],
87
- modified_files=['foo.c'],
88
- ignore_app_dependencies_filepatterns=['foo.c'],
89
- )
90
-
91
- for app in apps:
92
- assert app.build()
93
-
94
83
 
95
84
  @pytest.mark.skipif(not shutil.which('idf.py'), reason='idf.py not found')
96
85
  def test_idf_version_keywords_type():
@@ -3,7 +3,6 @@
3
3
 
4
4
  import logging
5
5
  import os
6
- import tempfile
7
6
  from pathlib import (
8
7
  Path,
9
8
  )
@@ -112,7 +111,7 @@ get-started:
112
111
  (['soc', 'fake'], True),
113
112
  ],
114
113
  )
115
- def test_with_depends_and_modified_components(self, tmpdir, modified_components, could_find_apps):
114
+ def test_with_requires_and_modified_components(self, tmpdir, modified_components, could_find_apps):
116
115
  test_dir = str(IDF_PATH / 'examples')
117
116
  apps = find_apps(test_dir, 'esp32', recursive=True)
118
117
  assert apps
@@ -184,13 +183,12 @@ get-started:
184
183
  assert not filtered_apps
185
184
 
186
185
  @pytest.mark.parametrize(
187
- 'modified_components, modified_files, could_find_apps',
186
+ 'modified_files, could_find_apps',
188
187
  [
189
- ([], '/foo', True),
190
- ([], str(IDF_PATH / 'examples' / 'README.md'), False),
191
- (None, [str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
188
+ ('/foo', True),
189
+ (str(IDF_PATH / 'examples' / 'README.md'), False),
190
+ ([str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
192
191
  (
193
- [],
194
192
  [
195
193
  str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md'),
196
194
  str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.c'),
@@ -199,7 +197,7 @@ get-started:
199
197
  ),
200
198
  ],
201
199
  )
202
- def test_with_depends_filepatterns(self, tmp_path, modified_components, modified_files, could_find_apps):
200
+ def test_with_depends_filepatterns(self, tmp_path, modified_files, could_find_apps):
203
201
  test_dir = str(IDF_PATH / 'examples' / 'get-started' / 'hello_world')
204
202
  apps = find_apps(test_dir, 'esp32', recursive=True)
205
203
  assert apps
@@ -222,39 +220,6 @@ get-started:
222
220
  recursive=True,
223
221
  manifest_rootpath=str(IDF_PATH),
224
222
  manifest_files=yaml_file,
225
- modified_components=modified_components,
226
- modified_files=modified_files,
227
- )
228
- if could_find_apps:
229
- assert filtered_apps == apps
230
- else:
231
- assert not filtered_apps
232
-
233
- @pytest.mark.parametrize(
234
- 'modified_files, could_find_apps',
235
- [
236
- (None, True),
237
- (str(IDF_PATH / 'examples' / 'README.md'), True),
238
- ([str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], True),
239
- (
240
- [
241
- str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md'),
242
- str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.c'),
243
- ],
244
- True,
245
- ),
246
- ([str(IDF_PATH / 'examples' / 'a.c')], True),
247
- ],
248
- )
249
- def test_with_filepattern_but_calculate_component_later(self, modified_files, could_find_apps):
250
- test_dir = str(IDF_PATH / 'examples' / 'get-started' / 'hello_world')
251
- apps = find_apps(test_dir, 'esp32', recursive=True)
252
- assert apps
253
-
254
- filtered_apps = find_apps(
255
- test_dir,
256
- 'esp32',
257
- recursive=True,
258
223
  modified_files=modified_files,
259
224
  )
260
225
  if could_find_apps:
@@ -418,84 +383,3 @@ class TestFindWithSdkconfigFiles:
418
383
  assert apps[0].sdkconfig_files == [
419
384
  str(tmp_path / 'test1' / 'sdkconfig.defaults'),
420
385
  ]
421
-
422
- def test_env_var(self, tmp_path, monkeypatch):
423
- create_project('test1', tmp_path)
424
-
425
- (tmp_path / 'test1' / 'sdkconfig.ci.foo').touch()
426
- (tmp_path / 'test1' / 'sdkconfig.ci.bar').touch()
427
- (tmp_path / 'test1' / 'sdkconfig.ci.baz').touch()
428
-
429
- yaml_file = tmp_path / 'test.yml'
430
- yaml_file.write_text(
431
- f'''
432
- {tmp_path}:
433
- enable:
434
- - if: CONFIG_NAME == "foo" and IDF_TARGET == "esp32"
435
- - if: CONFIG_NAME == "bar" and IDF_TARGET == "esp32s2"
436
- - if: TEST_ENV_VAR == "1"
437
- - if: CONFIG_NAME == "baz" and TEST_ENV_VAR == 0
438
- ''',
439
- encoding='utf8',
440
- )
441
-
442
- # in case you set it...
443
- monkeypatch.delenv('CONFIG_NAME', raising=False)
444
- monkeypatch.delenv('TEST_ENV_VAR', raising=False)
445
-
446
- # CONFIG_NAME should NOT be overridden by env var
447
- monkeypatch.setenv('CONFIG_NAME', 'bar')
448
- apps = find_apps(
449
- str(tmp_path / 'test1'),
450
- 'esp32',
451
- config_rules_str=['sdkconfig.ci=default', 'sdkconfig.ci.*='],
452
- manifest_files=yaml_file,
453
- )
454
- assert len(apps) == 2
455
- assert apps[0].sdkconfig_files == [
456
- str(tmp_path / 'test1' / 'sdkconfig.ci.baz'),
457
- ]
458
- assert apps[1].sdkconfig_files == [
459
- str(tmp_path / 'test1' / 'sdkconfig.ci.foo'),
460
- ]
461
- monkeypatch.delenv('CONFIG_NAME')
462
-
463
- # env var should be expanded
464
- monkeypatch.setenv('TEST_ENV_VAR', '1')
465
- apps = find_apps(
466
- str(tmp_path / 'test1'),
467
- 'esp32',
468
- config_rules_str=['sdkconfig.ci=default', 'sdkconfig.ci.*='],
469
- manifest_files=yaml_file,
470
- )
471
- assert len(apps) == 3
472
- monkeypatch.delenv('TEST_ENV_VAR')
473
-
474
-
475
- @pytest.mark.parametrize(
476
- 'exclude_list, apps_count',
477
- [
478
- (['test1'], 3), # not excluded
479
- (['folder1/test2'], 2),
480
- (['folder1'], 1),
481
- (['folder2/test2'], 2),
482
- ],
483
- )
484
- def test_find_apps_with_exclude(tmp_path, exclude_list, apps_count):
485
- (tmp_path / 'folder1').mkdir()
486
- (tmp_path / 'folder2').mkdir()
487
-
488
- create_project('test1', tmp_path / 'folder1')
489
- create_project('test2', tmp_path / 'folder1')
490
- create_project('test2', tmp_path / 'folder2')
491
-
492
- os.chdir(tmp_path)
493
- apps = find_apps(str(tmp_path), 'esp32', recursive=True, exclude_list=exclude_list)
494
- assert len(apps) == apps_count
495
-
496
- # or with absolute_path
497
- exclude_list = [os.path.abspath(x) for x in exclude_list]
498
- tmp_path = os.path.abspath(tmp_path)
499
- os.chdir(tempfile.tempdir)
500
- apps = find_apps(str(tmp_path), 'esp32', recursive=True, exclude_list=exclude_list)
501
- assert len(apps) == apps_count