azdev 0.2.13__tar.gz → 0.2.14__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.
- {azdev-0.2.13 → azdev-0.2.14}/HISTORY.rst +18 -0
- {azdev-0.2.13/azdev.egg-info → azdev-0.2.14}/PKG-INFO +27 -19
- {azdev-0.2.13 → azdev-0.2.14}/azdev/__init__.py +1 -1
- azdev-0.2.14/azdev/mod_templates/pyproject.toml +49 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/__init__.py +1 -2
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/cmdcov.py +1 -2
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/code_gen.py +1 -3
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/command_change/__init__.py +3 -14
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/command_change/custom.py +28 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/extensions/__init__.py +12 -29
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/extensions/metadata.py +21 -4
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/latest_index.py +1 -4
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/pypi.py +56 -50
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/regex.py +1 -2
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/statistics/__init__.py +3 -14
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/__init__.py +12 -0
- azdev-0.2.14/azdev/utilities/packaging.py +184 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/path.py +3 -2
- {azdev-0.2.13 → azdev-0.2.14/azdev.egg-info}/PKG-INFO +27 -19
- {azdev-0.2.13 → azdev-0.2.14}/azdev.egg-info/SOURCES.txt +2 -3
- {azdev-0.2.13 → azdev-0.2.14}/azdev.egg-info/requires.txt +6 -2
- azdev-0.2.14/pyproject.toml +111 -0
- azdev-0.2.13/azdev/mod_templates/setup.cfg +0 -0
- azdev-0.2.13/azdev/mod_templates/setup.py +0 -60
- azdev-0.2.13/pyproject.toml +0 -9
- azdev-0.2.13/setup.py +0 -112
- {azdev-0.2.13 → azdev-0.2.14}/LICENSE +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/MANIFEST.in +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/README.md +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/README.rst +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/__main__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/commands.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/completer.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/config/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/config/cli.flake8 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/config/cli_pylintrc +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/config/ext.flake8 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/config/ext_pylintrc +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/help.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/HISTORY.rst +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/README.rst +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/_client_factory.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/_help.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/_params.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/_validators.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/azext_metadata.json +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/blank__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/commands.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/custom.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/module__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/pkg_declare__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/mod_templates/test_service_scenario.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/breaking_change/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/breaking_change/markdown_template.jinja2 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/_macros.j2 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/component.css +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/component.js +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/favicon.ico +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/index.j2 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/index2.j2 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/cmdcov/module.j2 +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/command_change/util.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/constant.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/extensions/util.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/extensions/version_upgrade.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/help/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/help/refdoc/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/help/refdoc/conf.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/legal.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/data/cmd_example_config.json +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/linter.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/pylint_checkers/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/pylint_checkers/show_command.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rule_decorators.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/ci_exclusions.yml +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/command_coverage_rules.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/command_group_rules.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/command_rules.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/help_rules.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/linter_exclusions.yml +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/rules/parameter_rules.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/linter/util.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/performance.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/python_sdk.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/resource.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/secret.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/setup.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/statistics/util.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/style.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/testtool/__init__.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/testtool/incremental_strategy.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/testtool/profile_context.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/operations/testtool/pytest_runner.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/params.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/transformers.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/command.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/config.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/const.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/display.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/git_util.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/pypi.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/testing.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev/utilities/tools.py +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev.egg-info/dependency_links.txt +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev.egg-info/entry_points.txt +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/azdev.egg-info/top_level.txt +0 -0
- {azdev-0.2.13 → azdev-0.2.14}/setup.cfg +0 -0
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
Release History
|
|
4
4
|
===============
|
|
5
|
+
0.2.14
|
|
6
|
+
++++++
|
|
7
|
+
* `azdev extension add`/`list`/`build`: discover extensions by packaging configuration instead of globbing for `setup.py`, so extensions that have migrated to `pyproject.toml` are found. Previously a migrated extension was reported as `extension(s) not found`.
|
|
8
|
+
* `azdev extension build`: build through the PEP 517 frontend for `pyproject.toml` extensions, keeping `setup.py bdist_wheel` for the rest. `--no-isolation` preserves the previous behaviour for extensions whose build imports their own `azext_*` package.
|
|
9
|
+
* `azdev extension add`/`azdev setup`: generate `*.egg-info` without `setup.py`, so `az` can still discover a migrated extension as a development extension. `azure-cli-core` finds dev extensions by globbing `*.egg-info`.
|
|
10
|
+
* `azdev extension create`: scaffold `pyproject.toml` instead of `setup.py` and `setup.cfg`.
|
|
11
|
+
* `azdev extension update-index`: keep the home page under the `Home` label for `pyproject.toml` extensions, which declare `[project.urls] Homepage` rather than `url=`, so `index.json` entries do not change shape on migration. Also accept `License-Expression` in place of `License`.
|
|
12
|
+
* `azdev extension build`: fix the build-failure handler reading `CommandResultItem.output`, which does not exist. A failed build raised `AttributeError` instead of showing the build log.
|
|
13
|
+
* Migrate azdev and `azure-cli-diff-tool` to PEP 621 `pyproject.toml`. Both `setup.py` files are gone; wheel contents are unchanged.
|
|
14
|
+
* Build with `python -m build` in CI, and check metadata with `twine check` instead of `setup.py check -r -s`.
|
|
15
|
+
* Drop the `setuptools<80` cap. It guarded `setup.py develop`, which azdev stopped calling in 0.2.12. The `>=78.1.1` floor for CVE-2025-47273 stays.
|
|
16
|
+
* Fix `azdev cli check-versions` running `python -m setup.py bdist_wheel`, which could never work.
|
|
17
|
+
* Fix `azure-cli-diff-tool`'s sdist missing `HISTORY.rst`, which broke building a wheel from it.
|
|
18
|
+
* Fix `scripts/ci/extract_version.sh` producing an empty version.
|
|
19
|
+
* Set `Description-Content-Type` and stop reading the long description through `codecs.open`, which wrote `\r\r\n` line endings on Windows.
|
|
20
|
+
* `azdev command-change meta-export`: record `action` for parameters that take no value. Flag actions are written as `store_true`, `store_false`, `store_const` or `count`, including preview, experimental and deprecated arguments, whose action knack wraps in a subclass. Other actions registered with `nargs=0`, such as the one for `--acquire-policy-token`, are written as `store_true`. Readers of the metadata can now tell a flag such as `--enable-fips` from an option that takes a value. Other parameters get no `action` key, and `meta-diff` doesn't compare it.
|
|
21
|
+
* `azdev test`: cap `pytest` below 9.2. On Linux and macOS `azdev test` runs pytest with `--forked`, and pytest-forked 1.7.5 can't serialise pytest 9.2 reports, so every test failed with "EXITED with status 3". The cap stays until pytest-forked supports pytest 9.2 (pytest-dev/pytest-forked#113).
|
|
22
|
+
|
|
5
23
|
0.2.13
|
|
6
24
|
++++++
|
|
7
25
|
* `azdev extension add` / `azdev setup`: regenerate `*.egg-info` after the editable install so development extensions stay discoverable. `--no-build-isolation` (0.2.12) means pip no longer leaves an `*.egg-info` in the source tree, which made `azdev extension add` a silent no-op for discovery. (#554)
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: azdev
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.14
|
|
4
4
|
Summary: Microsoft Azure CLI Developer Tools
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: MIT
|
|
5
|
+
Author-email: Microsoft Corporation <azpycli@microsoft.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Azure/azure-cli-dev-tools
|
|
9
8
|
Keywords: azure
|
|
10
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: Topic :: Software Development :: Build Tools
|
|
13
12
|
Classifier: Environment :: Console
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
13
|
Classifier: Natural Language :: English
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -19,8 +17,10 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.14
|
|
21
19
|
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/x-rst
|
|
22
21
|
License-File: LICENSE
|
|
23
22
|
Requires-Dist: azure-multiapi-storage
|
|
23
|
+
Requires-Dist: build
|
|
24
24
|
Requires-Dist: docutils
|
|
25
25
|
Requires-Dist: flake8
|
|
26
26
|
Requires-Dist: gitpython
|
|
@@ -29,7 +29,7 @@ Requires-Dist: knack
|
|
|
29
29
|
Requires-Dist: pylint<5,>=4
|
|
30
30
|
Requires-Dist: pytest-xdist
|
|
31
31
|
Requires-Dist: pytest-forked
|
|
32
|
-
Requires-Dist: pytest
|
|
32
|
+
Requires-Dist: pytest<9.2,>=5.0.0
|
|
33
33
|
Requires-Dist: pyyaml
|
|
34
34
|
Requires-Dist: requests
|
|
35
35
|
Requires-Dist: sphinx==1.6.7
|
|
@@ -39,21 +39,12 @@ Requires-Dist: deepdiff~=8.6.1
|
|
|
39
39
|
Requires-Dist: azure-cli-diff-tool~=0.1.1
|
|
40
40
|
Requires-Dist: packaging
|
|
41
41
|
Requires-Dist: pkginfo
|
|
42
|
+
Requires-Dist: tomli; python_version < "3.11"
|
|
42
43
|
Requires-Dist: tqdm
|
|
43
|
-
Requires-Dist: setuptools
|
|
44
|
+
Requires-Dist: setuptools>=78.1.1
|
|
44
45
|
Requires-Dist: wheel
|
|
45
46
|
Requires-Dist: microsoft-security-utilities-secret-masker~=1.0.0b4
|
|
46
|
-
Dynamic: author
|
|
47
|
-
Dynamic: author-email
|
|
48
|
-
Dynamic: classifier
|
|
49
|
-
Dynamic: description
|
|
50
|
-
Dynamic: home-page
|
|
51
|
-
Dynamic: keywords
|
|
52
|
-
Dynamic: license
|
|
53
47
|
Dynamic: license-file
|
|
54
|
-
Dynamic: requires-dist
|
|
55
|
-
Dynamic: requires-python
|
|
56
|
-
Dynamic: summary
|
|
57
48
|
|
|
58
49
|
Microsoft Azure CLI Dev Tools (azdev)
|
|
59
50
|
=====================================
|
|
@@ -199,11 +190,28 @@ License
|
|
|
199
190
|
|
|
200
191
|
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.::
|
|
201
192
|
|
|
202
|
-
|
|
203
193
|
.. :changelog:
|
|
204
194
|
|
|
205
195
|
Release History
|
|
206
196
|
===============
|
|
197
|
+
0.2.14
|
|
198
|
+
++++++
|
|
199
|
+
* `azdev extension add`/`list`/`build`: discover extensions by packaging configuration instead of globbing for `setup.py`, so extensions that have migrated to `pyproject.toml` are found. Previously a migrated extension was reported as `extension(s) not found`.
|
|
200
|
+
* `azdev extension build`: build through the PEP 517 frontend for `pyproject.toml` extensions, keeping `setup.py bdist_wheel` for the rest. `--no-isolation` preserves the previous behaviour for extensions whose build imports their own `azext_*` package.
|
|
201
|
+
* `azdev extension add`/`azdev setup`: generate `*.egg-info` without `setup.py`, so `az` can still discover a migrated extension as a development extension. `azure-cli-core` finds dev extensions by globbing `*.egg-info`.
|
|
202
|
+
* `azdev extension create`: scaffold `pyproject.toml` instead of `setup.py` and `setup.cfg`.
|
|
203
|
+
* `azdev extension update-index`: keep the home page under the `Home` label for `pyproject.toml` extensions, which declare `[project.urls] Homepage` rather than `url=`, so `index.json` entries do not change shape on migration. Also accept `License-Expression` in place of `License`.
|
|
204
|
+
* `azdev extension build`: fix the build-failure handler reading `CommandResultItem.output`, which does not exist. A failed build raised `AttributeError` instead of showing the build log.
|
|
205
|
+
* Migrate azdev and `azure-cli-diff-tool` to PEP 621 `pyproject.toml`. Both `setup.py` files are gone; wheel contents are unchanged.
|
|
206
|
+
* Build with `python -m build` in CI, and check metadata with `twine check` instead of `setup.py check -r -s`.
|
|
207
|
+
* Drop the `setuptools<80` cap. It guarded `setup.py develop`, which azdev stopped calling in 0.2.12. The `>=78.1.1` floor for CVE-2025-47273 stays.
|
|
208
|
+
* Fix `azdev cli check-versions` running `python -m setup.py bdist_wheel`, which could never work.
|
|
209
|
+
* Fix `azure-cli-diff-tool`'s sdist missing `HISTORY.rst`, which broke building a wheel from it.
|
|
210
|
+
* Fix `scripts/ci/extract_version.sh` producing an empty version.
|
|
211
|
+
* Set `Description-Content-Type` and stop reading the long description through `codecs.open`, which wrote `\r\r\n` line endings on Windows.
|
|
212
|
+
* `azdev command-change meta-export`: record `action` for parameters that take no value. Flag actions are written as `store_true`, `store_false`, `store_const` or `count`, including preview, experimental and deprecated arguments, whose action knack wraps in a subclass. Other actions registered with `nargs=0`, such as the one for `--acquire-policy-token`, are written as `store_true`. Readers of the metadata can now tell a flag such as `--enable-fips` from an option that takes a value. Other parameters get no `action` key, and `meta-diff` doesn't compare it.
|
|
213
|
+
* `azdev test`: cap `pytest` below 9.2. On Linux and macOS `azdev test` runs pytest with `--forked`, and pytest-forked 1.7.5 can't serialise pytest 9.2 reports, so every test failed with "EXITED with status 3". The cap stays until pytest-forked supports pytest 9.2 (pytest-dev/pytest-forked#113).
|
|
214
|
+
|
|
207
215
|
0.2.13
|
|
208
216
|
++++++
|
|
209
217
|
* `azdev extension add` / `azdev setup`: regenerate `*.egg-info` after the editable install so development extensions stay discoverable. `--no-build-isolation` (0.2.12) means pip no longer leaves an `*.egg-info` in the source tree, which made `azdev extension add` a silent no-op for discovery. (#554)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=70.1.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "{{ pkg_name }}"
|
|
7
|
+
# TODO: Confirm this is the right version number you want and it matches your
|
|
8
|
+
# HISTORY.rst entry.
|
|
9
|
+
version = "0.1.0"
|
|
10
|
+
description = "Microsoft Azure Command-Line Tools {{ display_name }} {{ 'Extension' if is_ext else 'Command Module' }}"
|
|
11
|
+
# TODO: Update author and email, if applicable
|
|
12
|
+
authors = [{ name = "Microsoft Corporation", email = "azpycli@microsoft.com" }]
|
|
13
|
+
license = { text = "MIT" }
|
|
14
|
+
# The full list of classifiers is available at
|
|
15
|
+
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: System Administrators",
|
|
20
|
+
"Programming Language :: Python",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"License :: OSI Approved :: MIT License",
|
|
27
|
+
]
|
|
28
|
+
# TODO: Add any additional SDK dependencies here
|
|
29
|
+
dependencies = {% if dependencies %}[
|
|
30
|
+
{{ dependencies|join(',\n '|safe) }}
|
|
31
|
+
]{% else %}[]{% endif %}
|
|
32
|
+
# `readme` is the concatenation of README.rst and HISTORY.rst, which PEP 621
|
|
33
|
+
# cannot express statically.
|
|
34
|
+
dynamic = ["readme"]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
# TODO: change to your extension source code repo if the code will not be put in azure-cli-extensions repo
|
|
38
|
+
Homepage = "https://github.com/Azure/{% if is_ext %}azure-cli-extensions/tree/main/src/{{ pkg_name }}{% else %}azure-cli{% endif %}"
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.dynamic]
|
|
41
|
+
readme = { file = ["README.rst", "HISTORY.rst"], content-type = "text/x-rst" }
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["."]
|
|
45
|
+
exclude = ["tests*"]
|
|
46
|
+
{% if is_ext %}
|
|
47
|
+
[tool.setuptools.package-data]
|
|
48
|
+
{{ ext_long_name }} = ["azext_metadata.json"]
|
|
49
|
+
{% endif %}
|
|
@@ -21,8 +21,7 @@ logger = get_logger(__name__)
|
|
|
21
21
|
try:
|
|
22
22
|
with open(os.path.join(get_cli_repo_path(), 'scripts', 'ci', 'cmdcov.yml'), 'r') as file:
|
|
23
23
|
config = yaml.safe_load(file)
|
|
24
|
-
# pylint: disable=broad-exception-caught
|
|
25
|
-
except Exception:
|
|
24
|
+
except Exception: # pylint: disable=broad-exception-caught
|
|
26
25
|
url = "https://raw.githubusercontent.com/Azure/azure-cli/dev/scripts/ci/cmdcov.yml"
|
|
27
26
|
response = requests.get(url)
|
|
28
27
|
config = yaml.safe_load(response.text)
|
|
@@ -22,8 +22,7 @@ logger = get_logger(__name__)
|
|
|
22
22
|
try:
|
|
23
23
|
with open(os.path.join(get_cli_repo_path(), 'scripts', 'ci', 'cmdcov.yml'), 'r') as file:
|
|
24
24
|
config = yaml.safe_load(file)
|
|
25
|
-
# pylint: disable=broad-exception-caught
|
|
26
|
-
except Exception:
|
|
25
|
+
except Exception: # pylint: disable=broad-exception-caught
|
|
27
26
|
url = "https://raw.githubusercontent.com/Azure/azure-cli/dev/scripts/ci/cmdcov.yml"
|
|
28
27
|
response = requests.get(url)
|
|
29
28
|
config = yaml.safe_load(response.text)
|
|
@@ -30,7 +30,6 @@ def _ensure_dir(path):
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def _generate_files(env, generation_kwargs, file_list, dest_path):
|
|
33
|
-
|
|
34
33
|
# allow sending a single item
|
|
35
34
|
if not isinstance(file_list, list):
|
|
36
35
|
file_list = [file_list]
|
|
@@ -269,8 +268,7 @@ def _create_package(prefix, repo_path, is_ext, name='test', display_name=None, d
|
|
|
269
268
|
root_files = [
|
|
270
269
|
'HISTORY.rst',
|
|
271
270
|
'README.rst',
|
|
272
|
-
'
|
|
273
|
-
'setup.py'
|
|
271
|
+
'pyproject.toml'
|
|
274
272
|
]
|
|
275
273
|
_generate_files(env, kwargs, root_files, dest_path)
|
|
276
274
|
|
|
@@ -10,8 +10,9 @@ import time
|
|
|
10
10
|
|
|
11
11
|
from knack.log import get_logger
|
|
12
12
|
import azure_cli_diff_tool
|
|
13
|
-
from azdev.utilities import display, require_azure_cli, heading,
|
|
13
|
+
from azdev.utilities import display, require_azure_cli, heading, filter_by_git_diff, \
|
|
14
14
|
calc_selected_mod_names
|
|
15
|
+
from azdev.utilities.path import calc_selected_modules
|
|
15
16
|
from .custom import DiffExportFormat, get_commands_meta, STORED_DEPRECATION_KEY
|
|
16
17
|
from .util import export_commands_meta, dump_command_tree, add_to_command_tree
|
|
17
18
|
from ..statistics import _create_invoker_and_load_cmds, _get_command_source, \
|
|
@@ -32,19 +33,7 @@ def export_command_meta(modules=None, git_source=None, git_target=None, git_repo
|
|
|
32
33
|
meta_output_path=None):
|
|
33
34
|
require_azure_cli()
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
cli_only = modules == ['CLI']
|
|
37
|
-
ext_only = modules == ['EXT']
|
|
38
|
-
if cli_only or ext_only:
|
|
39
|
-
modules = None
|
|
40
|
-
|
|
41
|
-
selected_modules = get_path_table(include_only=modules, include_whl_extensions=include_whl_extensions)
|
|
42
|
-
|
|
43
|
-
if cli_only:
|
|
44
|
-
selected_modules['ext'] = {}
|
|
45
|
-
if ext_only:
|
|
46
|
-
selected_modules['core'] = {}
|
|
47
|
-
selected_modules['mod'] = {}
|
|
36
|
+
selected_modules = calc_selected_modules(modules, include_whl_extensions=include_whl_extensions)
|
|
48
37
|
|
|
49
38
|
# filter down to only modules that have changed based on git diff
|
|
50
39
|
selected_modules = filter_by_git_diff(selected_modules, git_source, git_target, git_repo)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# -----------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
+
import argparse
|
|
7
8
|
from enum import Enum
|
|
8
9
|
|
|
9
10
|
from knack.log import get_logger
|
|
@@ -13,6 +14,17 @@ logger = get_logger(__name__)
|
|
|
13
14
|
|
|
14
15
|
STORED_DEPRECATION_KEY = ["expiration", "target", "redirect", "hide"]
|
|
15
16
|
|
|
17
|
+
# actions that take no value, so a reader of the metadata can tell a flag from an option that needs one
|
|
18
|
+
FLAG_ACTIONS = ["store_true", "store_false", "store_const", "count"]
|
|
19
|
+
# knack wraps the action in a subclass for preview, experimental and deprecated arguments,
|
|
20
|
+
# so match classes by base class, checking subclasses before their bases
|
|
21
|
+
FLAG_ACTION_CLASSES = [
|
|
22
|
+
(argparse._StoreTrueAction, "store_true"), # pylint: disable=protected-access
|
|
23
|
+
(argparse._StoreFalseAction, "store_false"), # pylint: disable=protected-access
|
|
24
|
+
(argparse._StoreConstAction, "store_const"), # pylint: disable=protected-access
|
|
25
|
+
(argparse._CountAction, "count"), # pylint: disable=protected-access
|
|
26
|
+
]
|
|
27
|
+
|
|
16
28
|
|
|
17
29
|
class DiffExportFormat(Enum):
|
|
18
30
|
DICT = "dict"
|
|
@@ -98,6 +110,21 @@ def process_arg_type(argument_settings, para):
|
|
|
98
110
|
para["type"] = raw_type if raw_type in ["str", "int", "float", "bool", "file_type"] else "custom_type"
|
|
99
111
|
|
|
100
112
|
|
|
113
|
+
def process_arg_action(argument_settings, para):
|
|
114
|
+
action = argument_settings.get("action", None)
|
|
115
|
+
if isinstance(action, str):
|
|
116
|
+
if action in FLAG_ACTIONS:
|
|
117
|
+
para["action"] = action
|
|
118
|
+
elif isinstance(action, type):
|
|
119
|
+
for action_class, action_name in FLAG_ACTION_CLASSES:
|
|
120
|
+
if issubclass(action, action_class):
|
|
121
|
+
para["action"] = action_name
|
|
122
|
+
break
|
|
123
|
+
# a custom action that takes no value, such as the one for --acquire-policy-token
|
|
124
|
+
if "action" not in para and argument_settings.get("nargs", None) == 0:
|
|
125
|
+
para["action"] = "store_true"
|
|
126
|
+
|
|
127
|
+
|
|
101
128
|
def normalize_para_types(para):
|
|
102
129
|
type_string_opts = ["string", "str", "aazstrarg",
|
|
103
130
|
"aazresourcelocationarg", "aazresourcegroupnamearg", "aazresourceidarg",
|
|
@@ -159,6 +186,7 @@ def gen_command_meta(command_info, with_help=False, with_example=False):
|
|
|
159
186
|
process_arg_options(settings, para)
|
|
160
187
|
process_arg_options_deprecation(settings, para)
|
|
161
188
|
process_arg_type(settings, para)
|
|
189
|
+
process_arg_action(settings, para)
|
|
162
190
|
if settings.get("required", False):
|
|
163
191
|
para["required"] = True
|
|
164
192
|
if settings.get("choices", None):
|
|
@@ -15,8 +15,9 @@ from knack.prompting import prompt_y_n
|
|
|
15
15
|
from knack.util import CLIError
|
|
16
16
|
|
|
17
17
|
from azdev.utilities import (
|
|
18
|
-
cmd,
|
|
19
|
-
get_azure_config_dir, require_azure_cli, heading, subheading, quote_arg, EXTENSION_PREFIX
|
|
18
|
+
cmd, pip_cmd, display, get_ext_repo_paths, find_files, get_azure_config, get_azdev_config,
|
|
19
|
+
get_azure_config_dir, require_azure_cli, heading, subheading, quote_arg, EXTENSION_PREFIX,
|
|
20
|
+
build_package_wheel, find_package_configs_recursive, generate_egg_info)
|
|
20
21
|
from .version_upgrade import VersionUpgradeMod
|
|
21
22
|
|
|
22
23
|
logger = get_logger(__name__)
|
|
@@ -56,12 +57,7 @@ def _ensure_egg_info(path):
|
|
|
56
57
|
# extension is invisible even though pip succeeded. Regenerate it with the env's setuptools.
|
|
57
58
|
if find_files(path, '*.egg-info'):
|
|
58
59
|
return
|
|
59
|
-
result =
|
|
60
|
-
'setup.py egg_info',
|
|
61
|
-
"Generating metadata for '{}'...".format(path),
|
|
62
|
-
is_module=False,
|
|
63
|
-
cwd=path,
|
|
64
|
-
)
|
|
60
|
+
result = generate_egg_info(path, "Generating metadata for '{}'...".format(path))
|
|
65
61
|
if result.error:
|
|
66
62
|
raise result.error # pylint: disable=raising-bad-type
|
|
67
63
|
|
|
@@ -71,7 +67,7 @@ def add_extension(extensions):
|
|
|
71
67
|
ext_paths = get_ext_repo_paths()
|
|
72
68
|
if not ext_paths or ext_paths == ['_NONE_']:
|
|
73
69
|
raise CLIError('Extension repo path is empty. Please try `azdev extension repo add` to add an extension repo')
|
|
74
|
-
all_extensions =
|
|
70
|
+
all_extensions = find_package_configs_recursive(ext_paths)
|
|
75
71
|
|
|
76
72
|
if extensions == ['*']:
|
|
77
73
|
paths_to_add = [os.path.dirname(path) for path in all_extensions
|
|
@@ -168,7 +164,7 @@ def list_extensions():
|
|
|
168
164
|
installed_names = [x['name'] for x in installed]
|
|
169
165
|
results = []
|
|
170
166
|
|
|
171
|
-
for ext_path in
|
|
167
|
+
for ext_path in find_package_configs_recursive(dev_sources):
|
|
172
168
|
# skip non-extension packages that may be in the extension folder (for example, from a virtual environment)
|
|
173
169
|
try:
|
|
174
170
|
glob_pattern = os.path.join(os.path.split(ext_path)[0], '{}*'.format(EXTENSION_PREFIX))
|
|
@@ -301,9 +297,8 @@ def update_extension_index(extensions):
|
|
|
301
297
|
except IndexError:
|
|
302
298
|
raise CLIError('unable to parse extension name')
|
|
303
299
|
|
|
304
|
-
#
|
|
305
|
-
|
|
306
|
-
ext_dir = tempfile.mkdtemp(dir=extensions_dir)
|
|
300
|
+
# Create temporary directories for extraction and caching
|
|
301
|
+
ext_dir = tempfile.mkdtemp()
|
|
307
302
|
whl_cache_dir = tempfile.mkdtemp()
|
|
308
303
|
whl_cache = {}
|
|
309
304
|
ext_file = get_whl_from_url(ext_path, ext_path.split("/")[-1], whl_cache_dir, whl_cache)
|
|
@@ -334,7 +329,7 @@ def build_extensions(extensions, dist_dir='dist'):
|
|
|
334
329
|
ext_paths = get_ext_repo_paths()
|
|
335
330
|
if not ext_paths or ext_paths == ['_NONE_']:
|
|
336
331
|
raise CLIError('Extension repo path is empty. Please try `azdev extension repo add` to add an extension repo')
|
|
337
|
-
all_extensions =
|
|
332
|
+
all_extensions = find_package_configs_recursive(ext_paths)
|
|
338
333
|
|
|
339
334
|
paths_to_build = []
|
|
340
335
|
for path in all_extensions:
|
|
@@ -347,22 +342,10 @@ def build_extensions(extensions, dist_dir='dist'):
|
|
|
347
342
|
if extensions:
|
|
348
343
|
raise CLIError('extension(s) not found: {}'.format(' '.join(extensions)))
|
|
349
344
|
|
|
350
|
-
|
|
351
|
-
dist_dir = os.path.join(original_cwd, dist_dir)
|
|
345
|
+
dist_dir = os.path.join(os.getcwd(), dist_dir)
|
|
352
346
|
for path in paths_to_build:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
result = py_cmd(command, "Building extension '{}'...".format(path), is_module=False)
|
|
356
|
-
if result.error:
|
|
357
|
-
# py_cmd captures the build output; surface it so the real setup.py failure is visible
|
|
358
|
-
# instead of only the opaque CalledProcessError.
|
|
359
|
-
build_output = result.output
|
|
360
|
-
if isinstance(build_output, (bytes, bytearray)):
|
|
361
|
-
build_output = build_output.decode('utf-8', 'ignore')
|
|
362
|
-
if build_output:
|
|
363
|
-
logger.error(build_output)
|
|
364
|
-
raise result.error # pylint: disable=raising-bad-type
|
|
365
|
-
os.chdir(original_cwd)
|
|
347
|
+
display("Building extension '{}'...".format(path))
|
|
348
|
+
build_package_wheel(path, dist_dir)
|
|
366
349
|
|
|
367
350
|
|
|
368
351
|
def publish_extensions(extensions, storage_account, storage_account_key, storage_container,
|
|
@@ -82,6 +82,7 @@ def read_pkginfo(wheel_path: Path) -> Dict[str, Any]:
|
|
|
82
82
|
"description": whl.description,
|
|
83
83
|
"description_content_type": whl.description_content_type,
|
|
84
84
|
"license": whl.license,
|
|
85
|
+
"license_expression": getattr(whl, "license_expression", None),
|
|
85
86
|
"classifiers": list(whl.classifiers or []),
|
|
86
87
|
"requires_dist": list(whl.requires_dist or []),
|
|
87
88
|
"requires_python": whl.requires_python,
|
|
@@ -149,13 +150,27 @@ def _coerce_run_requires(requires_dist: List[str]) -> List[Dict[str, Any]]:
|
|
|
149
150
|
|
|
150
151
|
|
|
151
152
|
def _coerce_project_urls(project_urls: List[str], home_page: Optional[str]) -> Dict[str, str]:
|
|
153
|
+
"""Build the `project_urls` block, normalizing the home page label.
|
|
154
|
+
|
|
155
|
+
A `setup.py` package declares `url=`, which lands in the `Home-page` METADATA
|
|
156
|
+
field and has always been stored in `index.json` under the `Home` label.
|
|
157
|
+
PEP 621 has no `url` equivalent: a pyproject package declares
|
|
158
|
+
`[project.urls] Homepage`, which lands in `Project-URL` instead. Both are
|
|
159
|
+
mapped to `Home` so an extension's index entry keeps its shape when it
|
|
160
|
+
migrates.
|
|
161
|
+
"""
|
|
152
162
|
out: Dict[str, str] = {}
|
|
153
163
|
if home_page:
|
|
154
164
|
out["Home"] = home_page
|
|
155
165
|
for entry in project_urls or []:
|
|
156
|
-
if "," in entry:
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
if "," not in entry:
|
|
167
|
+
continue
|
|
168
|
+
label, url = entry.split(",", 1)
|
|
169
|
+
label, url = label.strip(), url.strip()
|
|
170
|
+
if label.lower() in ("home", "homepage", "home-page"):
|
|
171
|
+
out.setdefault("Home", url)
|
|
172
|
+
continue
|
|
173
|
+
out[label] = url
|
|
159
174
|
return out
|
|
160
175
|
|
|
161
176
|
|
|
@@ -180,7 +195,9 @@ def merge_to_index_metadata(pkg: Dict[str, Any], azext: Dict[str, Any]) -> Dict[
|
|
|
180
195
|
metadata["name"] = pkg.get("name")
|
|
181
196
|
metadata["version"] = pkg.get("version")
|
|
182
197
|
metadata["summary"] = pkg.get("summary")
|
|
183
|
-
|
|
198
|
+
# PEP 639 wheels carry the license as `License-Expression` rather than
|
|
199
|
+
# `License`, so accept either and keep a single `license` key in the index.
|
|
200
|
+
metadata["license"] = pkg.get("license") or pkg.get("license_expression")
|
|
184
201
|
metadata["metadata_version"] = pkg.get("metadata_version")
|
|
185
202
|
metadata["classifiers"] = pkg.get("classifiers") or []
|
|
186
203
|
metadata["extras"] = []
|
|
@@ -17,10 +17,7 @@ _LATEST_INDEX_SCRIPT = os.path.join('scripts', 'generate_latest_indices.py')
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _resolve_cli_repo_path(cli_path):
|
|
20
|
-
if cli_path
|
|
21
|
-
resolved = os.path.abspath(os.path.expanduser(cli_path))
|
|
22
|
-
else:
|
|
23
|
-
resolved = get_cli_repo_path()
|
|
20
|
+
resolved = os.path.abspath(os.path.expanduser(cli_path)) if cli_path else get_cli_repo_path()
|
|
24
21
|
|
|
25
22
|
if not resolved or resolved == '_NONE_':
|
|
26
23
|
raise CLIError('Azure CLI repo path is not configured. Specify `--cli` or run `azdev setup`.')
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
|
+
import tempfile
|
|
10
11
|
|
|
11
12
|
from docutils import core, io
|
|
12
13
|
|
|
@@ -14,16 +15,14 @@ from knack.log import get_logger
|
|
|
14
15
|
from knack.util import CLIError
|
|
15
16
|
|
|
16
17
|
from azdev.utilities import (
|
|
17
|
-
display, heading, subheading, cmd,
|
|
18
|
-
pip_cmd, COMMAND_MODULE_PREFIX, require_azure_cli
|
|
18
|
+
build_package_wheel, display, heading, subheading, cmd, get_package_config,
|
|
19
|
+
get_path_table, pip_cmd, COMMAND_MODULE_PREFIX, require_azure_cli)
|
|
19
20
|
|
|
20
21
|
logger = get_logger(__name__)
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
HISTORY_NAME = 'HISTORY.rst'
|
|
24
25
|
RELEASE_HISTORY_TITLE = 'Release History'
|
|
25
|
-
SETUP_PY_NAME = 'setup.py'
|
|
26
|
-
|
|
27
26
|
# modules which should not be included in setup.py
|
|
28
27
|
# because they aren't on PyPI
|
|
29
28
|
EXCLUDED_MODULES = ['azure-cli-testsdk']
|
|
@@ -59,7 +58,20 @@ def check_history():
|
|
|
59
58
|
display('OK')
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
def
|
|
61
|
+
def _get_built_package_metadata(mod_path):
|
|
62
|
+
from pkginfo import Wheel
|
|
63
|
+
|
|
64
|
+
with tempfile.TemporaryDirectory(prefix='azdev-package-metadata-') as output_dir:
|
|
65
|
+
wheel_path = build_package_wheel(mod_path, output_dir)
|
|
66
|
+
metadata = Wheel(wheel_path)
|
|
67
|
+
return {
|
|
68
|
+
'description': metadata.description,
|
|
69
|
+
'description_content_type': metadata.description_content_type,
|
|
70
|
+
'version': metadata.version,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _check_history_headings(mod_path, actual_version=None):
|
|
63
75
|
history_path = os.path.join(mod_path, HISTORY_NAME)
|
|
64
76
|
|
|
65
77
|
source_path = None
|
|
@@ -93,41 +105,57 @@ def _check_history_headings(mod_path):
|
|
|
93
105
|
"line after the 'Release History' heading.".format(history_path))
|
|
94
106
|
|
|
95
107
|
first_version_history = all_versions[0]
|
|
96
|
-
actual_version
|
|
97
|
-
|
|
98
|
-
|
|
108
|
+
if actual_version is None:
|
|
109
|
+
actual_version_result = cmd(sys.executable + ' setup.py --version', cwd=mod_path)
|
|
110
|
+
# command can output warnings as well, so we just want the last line, which should have the version
|
|
111
|
+
actual_version = actual_version_result.result.splitlines()[-1].strip()
|
|
99
112
|
if first_version_history != actual_version:
|
|
100
|
-
errors.append("The topmost version in {} does not match version {}
|
|
113
|
+
errors.append("The topmost version in {} does not match package version {}.".format(
|
|
101
114
|
history_path, actual_version))
|
|
102
115
|
return errors
|
|
103
116
|
|
|
104
117
|
|
|
105
118
|
def _check_readme_render(mod_path):
|
|
106
119
|
errors = []
|
|
107
|
-
|
|
108
|
-
if
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
package_config = get_package_config(mod_path)
|
|
121
|
+
if package_config and os.path.basename(package_config) == 'setup.py':
|
|
122
|
+
result = cmd(sys.executable + ' setup.py check -r -s', cwd=mod_path)
|
|
123
|
+
if result.exit_code:
|
|
124
|
+
# this outputs some warnings we don't care about
|
|
125
|
+
error_lines = []
|
|
126
|
+
target_line = 'The following syntax errors were detected'
|
|
127
|
+
suppress = True
|
|
128
|
+
logger.debug(result.error.output)
|
|
129
|
+
|
|
130
|
+
# TODO: Checks for syntax errors but potentially not other things
|
|
131
|
+
for line in result.error.output.splitlines():
|
|
132
|
+
line = str(line).strip()
|
|
133
|
+
if not suppress and line:
|
|
134
|
+
error_lines.append(line)
|
|
135
|
+
if target_line in line:
|
|
136
|
+
suppress = False
|
|
137
|
+
errors.append(os.linesep.join(error_lines))
|
|
138
|
+
errors += _check_history_headings(mod_path)
|
|
139
|
+
return errors
|
|
140
|
+
|
|
141
|
+
metadata = _get_built_package_metadata(mod_path)
|
|
142
|
+
content_type = (metadata.get('description_content_type') or 'text/x-rst').split(';', 1)[0].strip().lower()
|
|
143
|
+
if content_type == 'text/x-rst' and metadata.get('description'):
|
|
144
|
+
_, publication = core.publish_programmatically(
|
|
145
|
+
source_class=io.StringInput, source=metadata['description'],
|
|
146
|
+
source_path=None, destination_class=io.NullOutput, destination=None,
|
|
147
|
+
destination_path=None, reader=None, reader_name='standalone', parser=None,
|
|
148
|
+
parser_name='restructuredtext', writer=None, writer_name='null', settings=None,
|
|
149
|
+
settings_spec=None, settings_overrides={}, config_section=None, enable_exit_status=None)
|
|
150
|
+
if publication.writer.document.reporter.max_level >= 2:
|
|
151
|
+
errors.append('The package long description contains reStructuredText warnings or errors.')
|
|
152
|
+
errors += _check_history_headings(mod_path, actual_version=metadata['version'])
|
|
124
153
|
return errors
|
|
125
154
|
# endregion
|
|
126
155
|
|
|
127
156
|
|
|
128
157
|
# region verify PyPI versions
|
|
129
158
|
def verify_versions():
|
|
130
|
-
import tempfile
|
|
131
159
|
import shutil
|
|
132
160
|
|
|
133
161
|
require_azure_cli()
|
|
@@ -174,25 +202,6 @@ def verify_versions():
|
|
|
174
202
|
display('OK!')
|
|
175
203
|
|
|
176
204
|
|
|
177
|
-
def _get_module_versions(results, modules):
|
|
178
|
-
|
|
179
|
-
version_pattern = re.compile(r'.*(?P<ver>\d+.\d+.\d+).*')
|
|
180
|
-
|
|
181
|
-
for mod, mod_path in modules:
|
|
182
|
-
if not mod.startswith(COMMAND_MODULE_PREFIX) and mod != 'azure-cli':
|
|
183
|
-
mod = '{}{}'.format(COMMAND_MODULE_PREFIX, mod)
|
|
184
|
-
|
|
185
|
-
setup_path = find_files(mod_path, 'setup.py')
|
|
186
|
-
with open(setup_path[0], 'r') as f:
|
|
187
|
-
local_version = 'Unknown'
|
|
188
|
-
for line in f.readlines():
|
|
189
|
-
if line.strip().startswith('VERSION'):
|
|
190
|
-
local_version = version_pattern.match(line).group('ver')
|
|
191
|
-
break
|
|
192
|
-
results[mod]['local_version'] = local_version
|
|
193
|
-
return results
|
|
194
|
-
|
|
195
|
-
|
|
196
205
|
# pylint: disable=too-many-statements
|
|
197
206
|
def _compare_module_against_pypi(results, root_dir, mod, mod_path):
|
|
198
207
|
import zipfile
|
|
@@ -230,10 +239,7 @@ def _compare_module_against_pypi(results, root_dir, mod, mod_path):
|
|
|
230
239
|
# build from source and extract the version
|
|
231
240
|
setup_path = os.path.normpath(mod_path.strip())
|
|
232
241
|
os.chdir(setup_path)
|
|
233
|
-
|
|
234
|
-
if len(os.listdir(build_dir)) != 1:
|
|
235
|
-
raise CLIError('Unexpectedly found multiple build files found in {}.'.format(build_dir))
|
|
236
|
-
build_path = os.path.join(build_dir, os.listdir(build_dir)[0])
|
|
242
|
+
build_path = build_package_wheel(setup_path, build_dir)
|
|
237
243
|
build_version = version_pattern.match(build_path).group(1)
|
|
238
244
|
|
|
239
245
|
results[mod].update({
|
|
@@ -18,8 +18,7 @@ logger = get_logger(__name__)
|
|
|
18
18
|
try:
|
|
19
19
|
with open(os.path.join(get_cli_repo_path(), 'scripts', 'ci', 'cmdcov.yml'), 'r') as file:
|
|
20
20
|
config = yaml.safe_load(file)
|
|
21
|
-
# pylint: disable=broad-exception-caught
|
|
22
|
-
except Exception:
|
|
21
|
+
except Exception: # pylint: disable=broad-exception-caught
|
|
23
22
|
url = "https://raw.githubusercontent.com/Azure/azure-cli/dev/scripts/ci/cmdcov.yml"
|
|
24
23
|
response = requests.get(url)
|
|
25
24
|
config = yaml.safe_load(response.text)
|