idf-build-apps 1.0.0rc0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/test-build-idf-apps.yml +2 -1
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/CHANGELOG.md +8 -2
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/CONTRIBUTING.md +3 -2
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/PKG-INFO +2 -1
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/find_build.md +8 -9
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/manifest.md +2 -1
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/__init__.py +1 -1
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/finder.py +7 -3
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/main.py +4 -9
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/utils.py +13 -4
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/pyproject.toml +1 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/setup.py +2 -1
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/tests/test_finder.py +31 -3
- idf_build_apps-1.0.1/tests/test_utils.py +136 -0
- idf_build_apps-1.0.0rc0/tests/test_utils.py +0 -84
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.editorconfig +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.git-blame-ignore-revs +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.gitattributes +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/check-pre-commit.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/issue_comment.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/new_issues.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/new_prs.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/publish-pypi.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.github/workflows/test-build-docs.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.gitignore +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.pre-commit-config.yaml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/.readthedocs.yml +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/LICENSE +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/README.md +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/CHANGELOG.md +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/CONTRIBUTING.md +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/Makefile +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/_static/espressif-logo.svg +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/_static/theme_overrides.css +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/_templates/layout.html +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/api.rst +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/conf.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/config_file.md +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/docs/index.rst +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/__main__.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/app.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/config.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/constants.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/log.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/manifest/__init__.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/manifest/if_parser.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/manifest/manifest.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/idf_build_apps/manifest/soc_header.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/license_header.txt +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/tests/conftest.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/tests/test_build.py +0 -0
- {idf_build_apps-1.0.0rc0 → idf_build_apps-1.0.1}/tests/test_manifest.py +0 -0
|
@@ -60,6 +60,7 @@ jobs:
|
|
|
60
60
|
export PYENV_ROOT="$HOME/.pyenv" && export PATH="$PYENV_ROOT/bin:$PATH" && eval "$(pyenv init --path)"
|
|
61
61
|
pyenv global ${{ matrix.python-version }}
|
|
62
62
|
rm $(which python3)
|
|
63
|
+
echo "urllib3<1.25,>=1.21.1" >> $IDF_PATH/requirements.txt
|
|
63
64
|
bash $IDF_PATH/install.sh
|
|
64
65
|
. $IDF_PATH/export.sh
|
|
65
66
|
pip install idf_build_apps-*-py2.py3-none-any.whl
|
|
@@ -76,7 +77,7 @@ jobs:
|
|
|
76
77
|
needs: build-python-packages
|
|
77
78
|
strategy:
|
|
78
79
|
matrix:
|
|
79
|
-
idf-branch: [
|
|
80
|
+
idf-branch: [release-v4.3, release-v4.4, release-v5.0, release-v5.1]
|
|
80
81
|
runs-on: ubuntu-latest
|
|
81
82
|
container:
|
|
82
83
|
image: espressif/idf:${{ matrix.idf-branch }}
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [1.0.1] (2023-06-12)
|
|
6
|
+
|
|
7
|
+
## Fixed
|
|
8
|
+
|
|
9
|
+
- glob patterns are matched recursively
|
|
10
|
+
|
|
11
|
+
## [1.0.0] (2023-05-25)
|
|
6
12
|
|
|
7
13
|
## Added
|
|
8
14
|
|
|
@@ -130,7 +136,7 @@ This is the last version to support ESP-IDF v4.1 since it's EOL on Feb. 24th, 20
|
|
|
130
136
|
|
|
131
137
|
### Fixed
|
|
132
138
|
|
|
133
|
-
-
|
|
139
|
+
- Relative path defined in the manifest files depend on the current work path
|
|
134
140
|
|
|
135
141
|
Added `manifest_rootpath` argument in `find_apps()`. Will use this value instead as the root folder for calculating absolute path
|
|
136
142
|
|
|
@@ -6,9 +6,10 @@ Please use python 3.7+ for developing, but keep in mind that we need to support
|
|
|
6
6
|
|-----------------|---------------------------|
|
|
7
7
|
| 4.1 | 2.7, 3.4+ |
|
|
8
8
|
| 4.2 | 2.7, 3.4+ |
|
|
9
|
-
| 4.3 | 3.
|
|
10
|
-
| 4.4 | 3.
|
|
9
|
+
| 4.3 | 2.7, 3.4+ |
|
|
10
|
+
| 4.4 | 2.7, 3.4+ |
|
|
11
11
|
| 5.0 | 3.7+ |
|
|
12
|
+
| 5.1 | 3.7+ |
|
|
12
13
|
| master | 3.7+ |
|
|
13
14
|
|
|
14
15
|
## Setup the Dev Environment
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: idf-build-apps
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
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.*
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
19
|
Requires-Dist: pathlib; python_version < '3.4'
|
|
20
|
+
Requires-Dist: glob2; python_version < '3.5'
|
|
20
21
|
Requires-Dist: pyparsing
|
|
21
22
|
Requires-Dist: pyyaml
|
|
22
23
|
Requires-Dist: packaging
|
|
@@ -59,6 +59,7 @@ flowchart TB
|
|
|
59
59
|
end
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
(config-rules)=
|
|
62
63
|
### Config Rules
|
|
63
64
|
|
|
64
65
|
Config rule represents the sdkconfig file pattern and the config name. The syntax is simple: `[FILE_PATTERN]=[CONFIG_NAME]`.
|
|
@@ -96,10 +97,10 @@ For example, in project `test-1`:
|
|
|
96
97
|
- The wildcard matches two files. Build two apps based on each sdkconfig file.
|
|
97
98
|
- - ``sdkconfig.ci.foo``
|
|
98
99
|
- ``sdkconfig.ci.bar``
|
|
100
|
+
```
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
For each config rule, only one wildcard is supported.
|
|
102
|
+
```{note}
|
|
103
|
+
For each config rule, only one wildcard is supported.
|
|
103
104
|
```
|
|
104
105
|
|
|
105
106
|
### Placeholders for Work Directory and Build Directory
|
|
@@ -114,7 +115,7 @@ By default, `idf-build-apps` would use the project directory as the work directo
|
|
|
114
115
|
|
|
115
116
|
#### Build Directory
|
|
116
117
|
|
|
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
|
|
118
|
+
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.
|
|
118
119
|
|
|
119
120
|
By default, `idf-build-apps` would follow what ESP-IDF does, use `build` as the build directory.
|
|
120
121
|
|
|
@@ -127,6 +128,7 @@ Placeholders are a set of symbols, which could be used when setting work directo
|
|
|
127
128
|
- `@n`: Would be replaced by the project name.
|
|
128
129
|
- `@f`: Would be replaced by the escaped project path (replaced "/" to "_").
|
|
129
130
|
- `@i`: Would be replaced by the build index. (only available in `build` command)
|
|
131
|
+
- `@p`: Would be replaced by the parallel build index. (default to `1`, only available in `build` command)
|
|
130
132
|
|
|
131
133
|
For example,
|
|
132
134
|
|
|
@@ -160,11 +162,8 @@ The output would be:
|
|
|
160
162
|
|
|
161
163
|
Building apps is a process that build all the applications that are collected by the "finding apps" process.
|
|
162
164
|
|
|
163
|
-
```{
|
|
164
|
-
|
|
165
|
-
.. note::
|
|
166
|
-
|
|
167
|
-
Almost all CLI options that ``find`` supported are also supported in ``build`` command. You may call ``idf-build-apps find -h`` or ``idf-build-apps build -h`` for all possible CLI options.
|
|
165
|
+
```{note}
|
|
166
|
+
Almost all CLI options that ``find`` supported are also supported in ``build`` command. You may call ``idf-build-apps find -h`` or ``idf-build-apps build -h`` for all possible CLI options.
|
|
168
167
|
```
|
|
169
168
|
|
|
170
169
|
### Tips on `build` CLI Options
|
|
@@ -30,6 +30,7 @@ One typical manifest file look like this:
|
|
|
30
30
|
- `IDF_VERSION_MINOR`
|
|
31
31
|
- `IDF_VERSION_PATCH`
|
|
32
32
|
- `INCLUDE_DEFAULT` (The default value of officially supported targets is 1, otherwise is 0)
|
|
33
|
+
- `CONFIG_NAME` (config name defined in [](project:#config-rules))
|
|
33
34
|
- environment variables, default to `0` if not set
|
|
34
35
|
- String, must be double-quoted. e.g., `"esp32"`, `"12345"`
|
|
35
36
|
- Integer, support decimal and hex. e.g., `1`, `0xAB`
|
|
@@ -138,7 +139,7 @@ One app will be built when:
|
|
|
138
139
|
- Files that matches any of the specified `depends_filepatterns` in the corresponding manifest file are modified
|
|
139
140
|
- 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
|
|
|
141
|
-
For example, this is an app `
|
|
142
|
+
For example, this is an app `example/foo`, which depends on `comp1`, `comp2`, `comp3` and all files under `common_header_files`:
|
|
142
143
|
|
|
143
144
|
```yaml
|
|
144
145
|
examples/foo:
|
|
@@ -17,6 +17,7 @@ from .app import (
|
|
|
17
17
|
)
|
|
18
18
|
from .utils import (
|
|
19
19
|
config_rules_from_str,
|
|
20
|
+
to_absolute_path,
|
|
20
21
|
to_list,
|
|
21
22
|
)
|
|
22
23
|
|
|
@@ -165,15 +166,18 @@ def _find_apps(
|
|
|
165
166
|
|
|
166
167
|
# The remaining part is for recursive == True
|
|
167
168
|
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]
|
|
168
171
|
for root, dirs, _ in os.walk(path):
|
|
169
172
|
LOGGER.debug('Entering %s', root)
|
|
170
|
-
|
|
173
|
+
root_path = to_absolute_path(root)
|
|
174
|
+
if root_path in exclude_list:
|
|
171
175
|
LOGGER.debug('=> Skipping %s (excluded)', root)
|
|
172
176
|
del dirs[:]
|
|
173
177
|
continue
|
|
174
178
|
|
|
175
|
-
if
|
|
176
|
-
LOGGER.debug('=> Skipping %s (managed components)',
|
|
179
|
+
if root_path.parts[-1] == 'managed_components': # idf-component-manager
|
|
180
|
+
LOGGER.debug('=> Skipping %s (managed components)', root_path)
|
|
177
181
|
del dirs[:]
|
|
178
182
|
continue
|
|
179
183
|
|
|
@@ -498,11 +498,7 @@ def get_parser(): # type: () -> argparse.ArgumentParser
|
|
|
498
498
|
action='store_true',
|
|
499
499
|
help='Look for apps in the specified paths recursively',
|
|
500
500
|
)
|
|
501
|
-
common_args.add_argument(
|
|
502
|
-
'--exclude',
|
|
503
|
-
nargs='+',
|
|
504
|
-
help='Ignore specified directory (if --recursive is given)',
|
|
505
|
-
)
|
|
501
|
+
common_args.add_argument('--exclude', nargs='+', help='Ignore specified path (if --recursive is given)')
|
|
506
502
|
common_args.add_argument(
|
|
507
503
|
'--work-dir',
|
|
508
504
|
help='If set, the app is first copied into the specified directory, and then built. '
|
|
@@ -588,10 +584,9 @@ def get_parser(): # type: () -> argparse.ArgumentParser
|
|
|
588
584
|
'--ignore-app-dependencies-filepatterns',
|
|
589
585
|
nargs='*',
|
|
590
586
|
default=None,
|
|
591
|
-
help='space-separated list which specifies the file patterns used for ignoring the
|
|
592
|
-
'The `depends_components` and `depends_filepatterns` set in the manifest files will be ignored when any of '
|
|
593
|
-
'
|
|
594
|
-
'--modified-files',
|
|
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',
|
|
595
590
|
)
|
|
596
591
|
|
|
597
592
|
common_args.add_argument(
|
|
@@ -23,6 +23,12 @@ except ImportError:
|
|
|
23
23
|
pass
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
if sys.version_info < (3, 5):
|
|
27
|
+
import glob2 as glob
|
|
28
|
+
else:
|
|
29
|
+
import glob
|
|
30
|
+
|
|
31
|
+
|
|
26
32
|
class ConfigRule:
|
|
27
33
|
def __init__(self, file_name, config_name): # type: (str, str) -> None
|
|
28
34
|
"""
|
|
@@ -213,14 +219,17 @@ def files_matches_patterns(
|
|
|
213
219
|
patterns, # type: list[str] | str
|
|
214
220
|
rootpath=None, # type: str
|
|
215
221
|
): # type: (...) -> bool
|
|
216
|
-
# can't match
|
|
222
|
+
# can't match an absolute pattern with a relative path
|
|
217
223
|
# change all to absolute paths
|
|
218
224
|
files = [to_absolute_path(f, rootpath) for f in to_list(files)]
|
|
219
225
|
patterns = [to_absolute_path(p, rootpath) for p in to_list(patterns)]
|
|
220
226
|
|
|
227
|
+
matched_paths = set()
|
|
228
|
+
for pat in patterns:
|
|
229
|
+
matched_paths.update(glob.glob(str(pat), recursive=True))
|
|
230
|
+
|
|
221
231
|
for f in files:
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return True
|
|
232
|
+
if str(f) in matched_paths:
|
|
233
|
+
return True
|
|
225
234
|
|
|
226
235
|
return False
|
|
@@ -15,6 +15,7 @@ install_requires = \
|
|
|
15
15
|
extras_require = \
|
|
16
16
|
{":python_version < '3.11'": ['toml'],
|
|
17
17
|
":python_version < '3.4'": ['pathlib'],
|
|
18
|
+
":python_version < '3.5'": ['glob2'],
|
|
18
19
|
'doc': ['sphinx',
|
|
19
20
|
'sphinx-rtd-theme',
|
|
20
21
|
'sphinx_copybutton',
|
|
@@ -26,7 +27,7 @@ entry_points = \
|
|
|
26
27
|
{'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
|
|
27
28
|
|
|
28
29
|
setup(name='idf-build-apps',
|
|
29
|
-
version='1.0.
|
|
30
|
+
version='1.0.1',
|
|
30
31
|
description='Tools for building ESP-IDF related apps.',
|
|
31
32
|
author=None,
|
|
32
33
|
author_email='Fu Hanxi <fuhanxi@espressif.com>',
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
+
import tempfile
|
|
6
7
|
from pathlib import (
|
|
7
8
|
Path,
|
|
8
9
|
)
|
|
@@ -185,9 +186,8 @@ get-started:
|
|
|
185
186
|
@pytest.mark.parametrize(
|
|
186
187
|
'modified_components, modified_files, could_find_apps',
|
|
187
188
|
[
|
|
188
|
-
([], '/foo', True),
|
|
189
189
|
([], str(IDF_PATH / 'examples' / 'README.md'), False),
|
|
190
|
-
(None, [str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')],
|
|
190
|
+
(None, [str(IDF_PATH / 'examples' / 'get-started' / 'hello_world' / 'a.md')], False),
|
|
191
191
|
(
|
|
192
192
|
[],
|
|
193
193
|
[
|
|
@@ -208,7 +208,6 @@ get-started:
|
|
|
208
208
|
f'''
|
|
209
209
|
{test_dir}:
|
|
210
210
|
depends_filepatterns:
|
|
211
|
-
- /foo
|
|
212
211
|
- examples/get-started/hello_world/**
|
|
213
212
|
- examples/foo/**
|
|
214
213
|
''',
|
|
@@ -469,3 +468,32 @@ class TestFindWithSdkconfigFiles:
|
|
|
469
468
|
)
|
|
470
469
|
assert len(apps) == 3
|
|
471
470
|
monkeypatch.delenv('TEST_ENV_VAR')
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
@pytest.mark.parametrize(
|
|
474
|
+
'exclude_list, apps_count',
|
|
475
|
+
[
|
|
476
|
+
(['test1'], 3), # not excluded
|
|
477
|
+
(['folder1/test2'], 2),
|
|
478
|
+
(['folder1'], 1),
|
|
479
|
+
(['folder2/test2'], 2),
|
|
480
|
+
],
|
|
481
|
+
)
|
|
482
|
+
def test_find_apps_with_exclude(tmp_path, exclude_list, apps_count):
|
|
483
|
+
(tmp_path / 'folder1').mkdir()
|
|
484
|
+
(tmp_path / 'folder2').mkdir()
|
|
485
|
+
|
|
486
|
+
create_project('test1', tmp_path / 'folder1')
|
|
487
|
+
create_project('test2', tmp_path / 'folder1')
|
|
488
|
+
create_project('test2', tmp_path / 'folder2')
|
|
489
|
+
|
|
490
|
+
os.chdir(tmp_path)
|
|
491
|
+
apps = find_apps(str(tmp_path), 'esp32', recursive=True, exclude_list=exclude_list)
|
|
492
|
+
assert len(apps) == apps_count
|
|
493
|
+
|
|
494
|
+
# or with absolute_path
|
|
495
|
+
exclude_list = [os.path.abspath(x) for x in exclude_list]
|
|
496
|
+
tmp_path = os.path.abspath(tmp_path)
|
|
497
|
+
os.chdir(tempfile.tempdir)
|
|
498
|
+
apps = find_apps(str(tmp_path), 'esp32', recursive=True, exclude_list=exclude_list)
|
|
499
|
+
assert len(apps) == apps_count
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import (
|
|
5
|
+
Path,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from idf_build_apps.utils import (
|
|
11
|
+
files_matches_patterns,
|
|
12
|
+
get_parallel_start_stop,
|
|
13
|
+
rmdir,
|
|
14
|
+
to_absolute_path,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.mark.parametrize(
|
|
19
|
+
'patterns, expected',
|
|
20
|
+
[
|
|
21
|
+
('*.txt', ['test/inner', 'test/inner/test.txt', 'test/test.txt']),
|
|
22
|
+
(
|
|
23
|
+
['*.txt', '*.log'],
|
|
24
|
+
[
|
|
25
|
+
'test/inner',
|
|
26
|
+
'test/inner/build.log',
|
|
27
|
+
'test/inner/test.txt',
|
|
28
|
+
'test/test.txt',
|
|
29
|
+
],
|
|
30
|
+
),
|
|
31
|
+
],
|
|
32
|
+
)
|
|
33
|
+
def test_rmdir(tmpdir, patterns, expected):
|
|
34
|
+
test_dir = tmpdir.mkdir('test')
|
|
35
|
+
dir1 = test_dir.mkdir('inner')
|
|
36
|
+
test_dir.mkdir('inner2')
|
|
37
|
+
|
|
38
|
+
Path(dir1 / 'test.txt').touch()
|
|
39
|
+
Path(dir1 / 'build.log').touch()
|
|
40
|
+
Path(test_dir / 'test.txt').touch()
|
|
41
|
+
|
|
42
|
+
rmdir(test_dir, exclude_file_patterns=patterns)
|
|
43
|
+
|
|
44
|
+
assert sorted(Path(test_dir).glob('**/*')) == [Path(tmpdir / i) for i in expected]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.mark.parametrize(
|
|
48
|
+
'total, parallel_count, parallel_index, start, stop',
|
|
49
|
+
[
|
|
50
|
+
(1, 1, 1, 1, 1),
|
|
51
|
+
(1, 2, 2, 2, 1),
|
|
52
|
+
(1, 10, 1, 1, 1),
|
|
53
|
+
(6, 4, 1, 1, 2),
|
|
54
|
+
(6, 4, 2, 3, 4),
|
|
55
|
+
(6, 4, 3, 5, 6),
|
|
56
|
+
(6, 4, 4, 7, 6),
|
|
57
|
+
(10, 10, 9, 9, 9),
|
|
58
|
+
(33, 2, 1, 1, 17),
|
|
59
|
+
(33, 2, 2, 18, 33),
|
|
60
|
+
],
|
|
61
|
+
)
|
|
62
|
+
def test_get_parallel_start_stop(total, parallel_count, parallel_index, start, stop):
|
|
63
|
+
assert (start, stop) == get_parallel_start_stop(total, parallel_count, parallel_index)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_files_matches_patterns(tmpdir):
|
|
67
|
+
# used for testing absolute paths
|
|
68
|
+
temp_dir = tmpdir.mkdir('temp')
|
|
69
|
+
os.chdir(temp_dir)
|
|
70
|
+
|
|
71
|
+
# create real files
|
|
72
|
+
test_dir = tmpdir.mkdir('test')
|
|
73
|
+
a_dir = test_dir.mkdir('a')
|
|
74
|
+
b_dir = a_dir.mkdir('b')
|
|
75
|
+
c_dir = b_dir.mkdir('c')
|
|
76
|
+
b_py = Path(a_dir / 'b.py')
|
|
77
|
+
c_py = Path(b_dir / 'c.py')
|
|
78
|
+
d_py = Path(c_dir / 'd.py')
|
|
79
|
+
b_py.touch()
|
|
80
|
+
c_py.touch()
|
|
81
|
+
d_py.touch()
|
|
82
|
+
|
|
83
|
+
# ├── temp
|
|
84
|
+
# └── test
|
|
85
|
+
# └── a
|
|
86
|
+
# ├── b
|
|
87
|
+
# │ ├── c
|
|
88
|
+
# │ │ └── d.py
|
|
89
|
+
# │ └── c.py
|
|
90
|
+
# ├── .hidden
|
|
91
|
+
# └── b.py
|
|
92
|
+
#
|
|
93
|
+
|
|
94
|
+
# in correct relative path
|
|
95
|
+
for matched_files, pat, rootpath in [
|
|
96
|
+
([b_py], '*.py', a_dir),
|
|
97
|
+
([b_py, c_py, d_py], '**/*.py', a_dir),
|
|
98
|
+
([c_py], '*.py', b_dir),
|
|
99
|
+
([c_py, d_py], '**/*.py', b_dir),
|
|
100
|
+
([d_py], '*.py', c_dir),
|
|
101
|
+
([d_py], '**/*.py', c_dir),
|
|
102
|
+
]:
|
|
103
|
+
for f in matched_files:
|
|
104
|
+
assert files_matches_patterns(f, pat, rootpath)
|
|
105
|
+
|
|
106
|
+
# in None root path with relative pattern
|
|
107
|
+
for matched_files, pat in [
|
|
108
|
+
([b_py], 'a/*.py'),
|
|
109
|
+
([b_py, c_py, d_py], 'a/**/*.py'),
|
|
110
|
+
([c_py], 'a/b/*.py'),
|
|
111
|
+
([c_py, d_py], 'a/b/**/*.py'),
|
|
112
|
+
([d_py], 'a/b/c/*.py'),
|
|
113
|
+
([d_py], 'a/b/c/**/*.py'),
|
|
114
|
+
]:
|
|
115
|
+
for f in matched_files:
|
|
116
|
+
# with correct pwd
|
|
117
|
+
os.chdir(test_dir)
|
|
118
|
+
assert files_matches_patterns(f, pat)
|
|
119
|
+
|
|
120
|
+
# with wrong pwd
|
|
121
|
+
os.chdir(temp_dir)
|
|
122
|
+
assert not files_matches_patterns(f, pat)
|
|
123
|
+
|
|
124
|
+
# use correct absolute path, in wrong pwd
|
|
125
|
+
for matched_files, pat in [
|
|
126
|
+
([b_py], 'a/*.py'),
|
|
127
|
+
([b_py, c_py, d_py], 'a/**/*.py'),
|
|
128
|
+
([c_py], 'a/b/*.py'),
|
|
129
|
+
([c_py, d_py], 'a/b/**/*.py'),
|
|
130
|
+
([d_py], 'a/b/c/*.py'),
|
|
131
|
+
([d_py], 'a/b/c/**/*.py'),
|
|
132
|
+
]:
|
|
133
|
+
abs_pat = to_absolute_path(pat, test_dir)
|
|
134
|
+
os.chdir(temp_dir)
|
|
135
|
+
for f in matched_files:
|
|
136
|
+
assert files_matches_patterns(f, abs_pat)
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
from pathlib import (
|
|
5
|
-
Path,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
import pytest
|
|
9
|
-
|
|
10
|
-
from idf_build_apps.utils import (
|
|
11
|
-
files_matches_patterns,
|
|
12
|
-
get_parallel_start_stop,
|
|
13
|
-
rmdir,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@pytest.mark.parametrize(
|
|
18
|
-
'patterns, expected',
|
|
19
|
-
[
|
|
20
|
-
('*.txt', ['test/inner', 'test/inner/test.txt', 'test/test.txt']),
|
|
21
|
-
(
|
|
22
|
-
['*.txt', '*.log'],
|
|
23
|
-
[
|
|
24
|
-
'test/inner',
|
|
25
|
-
'test/inner/build.log',
|
|
26
|
-
'test/inner/test.txt',
|
|
27
|
-
'test/test.txt',
|
|
28
|
-
],
|
|
29
|
-
),
|
|
30
|
-
],
|
|
31
|
-
)
|
|
32
|
-
def test_rmdir(tmpdir, patterns, expected):
|
|
33
|
-
test_dir = tmpdir.mkdir('test')
|
|
34
|
-
dir1 = test_dir.mkdir('inner')
|
|
35
|
-
test_dir.mkdir('inner2')
|
|
36
|
-
|
|
37
|
-
Path(dir1 / 'test.txt').touch()
|
|
38
|
-
Path(dir1 / 'build.log').touch()
|
|
39
|
-
Path(test_dir / 'test.txt').touch()
|
|
40
|
-
|
|
41
|
-
rmdir(test_dir, exclude_file_patterns=patterns)
|
|
42
|
-
|
|
43
|
-
assert sorted(Path(test_dir).glob('**/*')) == [Path(tmpdir / i) for i in expected]
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@pytest.mark.parametrize(
|
|
47
|
-
'total, parallel_count, parallel_index, start, stop',
|
|
48
|
-
[
|
|
49
|
-
(1, 1, 1, 1, 1),
|
|
50
|
-
(1, 2, 2, 2, 1),
|
|
51
|
-
(1, 10, 1, 1, 1),
|
|
52
|
-
(6, 4, 1, 1, 2),
|
|
53
|
-
(6, 4, 2, 3, 4),
|
|
54
|
-
(6, 4, 3, 5, 6),
|
|
55
|
-
(6, 4, 4, 7, 6),
|
|
56
|
-
(10, 10, 9, 9, 9),
|
|
57
|
-
(33, 2, 1, 1, 17),
|
|
58
|
-
(33, 2, 2, 18, 33),
|
|
59
|
-
],
|
|
60
|
-
)
|
|
61
|
-
def test_get_parallel_start_stop(total, parallel_count, parallel_index, start, stop):
|
|
62
|
-
assert (start, stop) == get_parallel_start_stop(total, parallel_count, parallel_index)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@pytest.mark.parametrize(
|
|
66
|
-
'files, patterns, rootpath, result',
|
|
67
|
-
[
|
|
68
|
-
('c.py', '*.py', None, True),
|
|
69
|
-
('c.py', '*.py', '/a', True),
|
|
70
|
-
('/a/b/c.py', 'c.py', None, False),
|
|
71
|
-
('/a/b/c.py', 'c.py', '/a/b', True),
|
|
72
|
-
('/a/b/../b/c.py', '*.py', None, False),
|
|
73
|
-
('/a/b/../b/c.py', '*.py', '/a/b', True),
|
|
74
|
-
('/a/b/../b/c.py', '**/*.py', None, False),
|
|
75
|
-
('/a/b/../b/c.py', '**/*.py', '/a', True),
|
|
76
|
-
('c.py', '/a/**/*.py', None, False),
|
|
77
|
-
('c.py', '/a/**/*.py', '/a', False),
|
|
78
|
-
('c.py', '/a/**/*.py', '/a/b', True),
|
|
79
|
-
('/a/b/c.py', '/a/**/*.py', None, True),
|
|
80
|
-
('/a/b/c.py', '/a/**/*.py', 'foo', True),
|
|
81
|
-
],
|
|
82
|
-
)
|
|
83
|
-
def test_files_matches_patterns(files, patterns, rootpath, result):
|
|
84
|
-
assert files_matches_patterns(files, patterns, rootpath) == result
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|