зеркало из
1
0
Форкнуть 0

Replace compile-time `validateFormatting` parameter (#38212)

* transition validate_formatting.py to run_black.py called from within the tox env
* update filter_tox_env_string to handle check defaults that are nonTrue
* default black to opt-in, not opt-out
This commit is contained in:
Scott Beddall 2024-11-19 14:11:55 -08:00 коммит произвёл GitHub
Родитель 947ad7cdf8
Коммит 69f0c227c0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
34 изменённых файлов: 118 добавлений и 152 удалений

Просмотреть файл

@ -112,6 +112,8 @@ This is the most useful skip, but the following skip variables are also supporte
- Omit checking that a package's dependencies are on PyPI before releasing.
- `Skip.KeywordCheck`
- Omit checking that a package's keywords are correctly formulated before releasing.
- `Skip.Black`
- Omit checking `black` in the `analyze` job.
## The pyproject.toml
@ -172,7 +174,7 @@ You can enable test logging in a pipeline by setting the queue time variable `PY
`PYTEST_LOG_LEVEL=INFO`
This also works locally with tox by setting the `PYTEST_LOG_LEVEL` environment variable.
This also works locally with tox by setting the `PYTEST_LOG_LEVEL` environment variable.
Note that if you want DEBUG level logging with sensitive information unredacted in the test logs, then you still must pass `logging_enable=True` into the client(s) being used in tests.
@ -237,17 +239,17 @@ fail if docstring are invalid, helping to ensure the resulting documentation wil
#### Opt-in to formatting validation
Make the following change to your projects `ci.yml`:
Ensure that `black = true` is present within your `pyproject.toml`:
```yml
extends:
template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml
parameters:
...
ValidateFormatting: true
...
[tool.azure-sdk-build]
...other checks enabled/disabled
black = true
...other checks enabled/disabled
```
to opt into the black invocation.
#### Running locally
1. Go to package root directory.

Просмотреть файл

@ -49,9 +49,6 @@ parameters:
- name: VerifyAutorest
type: boolean
default: false
- name: ValidateFormatting
type: boolean
default: false
- name: UnsupportedToxEnvironments
type: string
default: ''
@ -229,7 +226,6 @@ jobs:
TestPipeline: ${{ parameters.TestPipeline }}
Artifacts: ${{ parameters.Artifacts }}
VerifyAutorest: ${{ parameters.VerifyAutorest }}
ValidateFormatting: ${{ parameters.ValidateFormatting }}
GenerateApiReviewForManualOnly: ${{ parameters.GenerateApiReviewForManualOnly }}
- template: /eng/common/pipelines/templates/jobs/generate-job-matrix.yml

Просмотреть файл

@ -63,9 +63,6 @@ parameters:
- name: VerifyAutorest
type: boolean
default: false
- name: ValidateFormatting
type: boolean
default: false
- name: TestProxy
type: boolean
default: true
@ -107,7 +104,6 @@ extends:
MatrixFilters: ${{ parameters.MatrixFilters }}
MatrixReplace: ${{ parameters.MatrixReplace }}
VerifyAutorest: ${{ parameters.VerifyAutorest }}
ValidateFormatting: ${{ parameters.ValidateFormatting }}
TestProxy: ${{ parameters.TestProxy }}
GenerateApiReviewForManualOnly: ${{ parameters.GenerateApiReviewForManualOnly }}

Просмотреть файл

@ -5,7 +5,6 @@ parameters:
Artifacts: []
TestPipeline: false
VerifyAutorest: false
ValidateFormatting: false
GenerateApiReviewForManualOnly: false
# Please use `$(TargetingString)` to refer to the python packages glob string. This variable is set from resolve-package-targeting.yml.
@ -110,11 +109,9 @@ steps:
ServiceDirectory: ${{ parameters.ServiceDirectory }}
AdditionalTestArgs: ${{ parameters.AdditionalTestArgs }}
- ${{ if parameters.ValidateFormatting }}:
- template: run_black.yml
parameters:
ServiceDirectory: ${{ parameters.ServiceDirectory }}
ValidateFormatting: ${{ parameters.ValidateFormatting }}
- template: run_black.yml
parameters:
ServiceDirectory: ${{ parameters.ServiceDirectory }}
- task: PythonScript@0
displayName: 'Run Keyword Validation Check'

Просмотреть файл

@ -1,6 +1,5 @@
parameters:
ServiceDirectory: ''
ValidateFormatting: false
EnvVars: {}
AdditionalTestArgs: ''
@ -19,10 +18,13 @@ steps:
- task: PythonScript@0
displayName: 'Run Black'
inputs:
scriptPath: 'scripts/devops_tasks/validate_formatting.py'
scriptPath: 'scripts/devops_tasks/dispatch_tox.py'
arguments: >-
"$(TargetingString)"
--service_directory="${{ parameters.ServiceDirectory }}"
--validate="${{ parameters.ValidateFormatting }}"
--mark_arg="${{ parameters.TestMarkArgument }}"
--service="${{ parameters.ServiceDirectory }}"
--toxenv="black"
--filter-type="Omit_management"
${{ parameters.AdditionalTestArgs }}
env: ${{ parameters.EnvVars }}
condition: and(succeededOrFailed(), ne(variables['Skip.Pylint'],'true'))
condition: and(succeededOrFailed(), ne(variables['Skip.Black'],'true'))

75
eng/tox/run_black.py Normal file
Просмотреть файл

@ -0,0 +1,75 @@
#!/usr/bin/env python
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# This script is used to execute pylint within a tox environment. Depending on which package is being executed against,
# a failure may be suppressed.
import subprocess
import argparse
import os
import logging
import sys
from ci_tools.environment_exclusions import is_check_enabled
from ci_tools.parsing import ParsedSetup
from ci_tools.variables import in_ci
logging.getLogger().setLevel(logging.INFO)
root_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", ".."))
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Run black against target folder. Uses the black config in eng/black-pyproject.toml."
)
parser.add_argument(
"-t",
"--target",
dest="target_package",
help="The target package directory on disk.",
required=True,
)
args = parser.parse_args()
pkg_dir = os.path.abspath(args.target_package)
pkg_details = ParsedSetup.from_path(pkg_dir)
configFileLocation = os.path.join(root_dir, "eng/black-pyproject.toml")
if in_ci():
if not is_check_enabled(args.target_package, "black"):
logging.info(
f"Package {pkg_details.name} opts-out of black check."
)
exit(0)
try:
run_result = subprocess.run(
[
sys.executable,
"-m",
"black",
f"--config={configFileLocation}",
args.target_package,
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
if run_result.stderr and "reformatted" in run_result.stderr.decode("utf-8"):
if in_ci():
logging.info(f"The package {pkg_details.name} needs reformat. Run the `black` tox env locally to reformat.")
exit(1)
else:
logging.info(f"The package {pkg_details.name} was reformatted.")
except subprocess.CalledProcessError as e:
logging.error(
f"Unable to invoke black for {pkg_details.name}. Ran into exception {e}."
)

Просмотреть файл

@ -531,9 +531,9 @@ description=Runs the code formatter black
skip_install=true
deps=
black==24.4.0
-rdev_requirements.txt
commands=
black --config {repository_root}/eng/black-pyproject.toml {posargs}
python {repository_root}/eng/tox/run_black.py -t {tox_root}
[testenv:generate]
description=Regenerate the code

Просмотреть файл

@ -1,107 +0,0 @@
#!/usr/bin/env python
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import argparse
import os
import logging
import sys
import subprocess
logging.getLogger().setLevel(logging.INFO)
from ci_tools.functions import discover_targeted_packages
from ci_tools.environment_exclusions import is_check_enabled
root_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", ".."))
sdk_dir = os.path.join(root_dir, "sdk")
def run_black(glob_string, service_dir):
results = []
logging.info("Running black for {}".format(service_dir))
if service_dir and service_dir != "auto":
target_dir = os.path.join(root_dir, "sdk", service_dir)
else:
target_dir = root_dir
discovered_packages = discover_targeted_packages(glob_string, target_dir)
for package in discovered_packages:
package_name = os.path.basename(package)
if is_check_enabled(package, "black", True):
out = subprocess.Popen(
[
"tox",
"-qqq",
"--conf",
os.path.join(root_dir, "eng", "tox", "tox.ini"),
"--root",
root_dir,
"run",
"-e",
"black",
"--",
package,
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=root_dir,
)
stdout, stderr = out.communicate()
if stderr:
results.append((package_name, stderr))
if out.returncode > 0:
print(
f"black ran into an unexpected failure while analyzing the code for {package_name}"
)
if stdout:
print(stdout.decode("utf-8"))
exit(out.returncode)
if stdout and "reformatted" in stdout.decode("utf-8"):
results.append((package_name, False))
else:
print(f"black succeeded against {package_name}")
return results
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Run black to verify formatted code.")
parser.add_argument(
"glob_string",
nargs="?",
help=(
"A comma separated list of glob strings that will target the top level directories that contain packages."
'Examples: All = "azure*", Single = "azure-keyvault", Targeted Multiple = "azure-keyvault,azure-mgmt-resource"'
),
)
parser.add_argument(
"--service_directory", help="Directory of the package being tested"
)
parser.add_argument("--validate", help=("Flag that enables formatting validation."))
args = parser.parse_args()
if args.validate != "False":
results = run_black(args.glob_string, args.service_directory)
if len(results) > 0:
for result in results:
error = "Code needs reformat." if result[1] == False else error
logging.error(f"Black run for {result[0]} ran into an issue: {error}")
raise ValueError(
"Found difference between formatted code and current commit. Check https://aka.ms/azsdk/python/black for how to fix it."
)
else:
print("Skipping formatting validation")

Просмотреть файл

@ -1,2 +1,3 @@
[tool.azure-sdk-build]
pyright = false
black = true

Просмотреть файл

@ -1,2 +1,3 @@
[tool.azure-sdk-build]
pyright = false
black = true

Просмотреть файл

@ -31,7 +31,6 @@ extends:
TestProxy: true
ServiceDirectory: appconfiguration
VerifyAutorest: false
ValidateFormatting: true
Artifacts:
- name: azure-appconfiguration
safeName: azureappconfiguration

Просмотреть файл

@ -1,2 +1,3 @@
[tool.azure-sdk-build]
pyright = false
black = true

Просмотреть файл

@ -1,2 +1,3 @@
[tool.azure-sdk-build]
breaking = false
black = true

Просмотреть файл

@ -30,7 +30,6 @@ extends:
parameters:
TestProxy: true
ServiceDirectory: containerregistry
ValidateFormatting: true
Artifacts:
- name: azure-mgmt-containerregistry
safeName: azuremgmtcontainerregistry

Просмотреть файл

@ -2,3 +2,4 @@
type_check_samples = false
pyright = false
mypy = true
black = true

Просмотреть файл

@ -1,3 +1,4 @@
[tool.azure-sdk-build]
type_check_samples = false
pyright = false
black = true

Просмотреть файл

@ -3,6 +3,7 @@ mypy = true
type_check_samples = true
verifytypes = true
pyright = false
black = true
# For test environments or static checks where a check should be run by default, not explicitly disabling will enable the check.
# pylint is enabled by default, so there is no reason for a pylint = true in every pyproject.toml.
#

Просмотреть файл

@ -4,3 +4,4 @@ verifytypes = true
pyright = false
type_check_samples = false
breaking = false
black = true

Просмотреть файл

@ -36,7 +36,6 @@ extends:
parameters:
ServiceDirectory: core
BuildTargetingString: "*"
ValidateFormatting: true
TestProxy: false
TestTimeoutInMinutes: 120
Artifacts:

Просмотреть файл

@ -1,3 +1,4 @@
[tool.azure-sdk-build]
pyright = false
verify_keywords = false
black = true

Просмотреть файл

@ -26,7 +26,6 @@ extends:
template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml
parameters:
ServiceDirectory: evaluation
ValidateFormatting: true
TestProxy: true
# This custom matrix config should be dropped once:
# * Once azure-ai-ml supports 3.13 (currently crashes due to type annotation)

Просмотреть файл

@ -1,3 +1,4 @@
[tool.azure-sdk-build]
type_check_samples = false
pyright = false
pyright = false
black = true

Просмотреть файл

@ -1,3 +1,4 @@
[tool.azure-sdk-build]
pyright = false
verifytypes = true
black = true

Просмотреть файл

@ -35,7 +35,6 @@ extends:
Path: sdk/identity/platform-matrix.json
Selection: sparse
GenerateVMJobs: true
ValidateFormatting: true
TestProxy: true
Artifacts:
- name: azure-identity

Просмотреть файл

@ -5,6 +5,7 @@ type_check_samples = false
pylint = true
mindependency = false
latestdependency = false
black = true
[tool.isort]
profile = "black"

Просмотреть файл

@ -30,7 +30,6 @@ extends:
template: /eng/pipelines/templates/stages/archetype-sdk-client.yml
parameters:
ServiceDirectory: ml
ValidateFormatting: true
TestTimeoutInMinutes: 75
TestProxy: true
MatrixFilters:

Просмотреть файл

@ -4,3 +4,4 @@ pyright = false
type_check_samples = false
verifytypes = false
ci_enabled = false
black = true

Просмотреть файл

@ -28,7 +28,6 @@ extends:
parameters:
ServiceDirectory: personalizer
TestProxy: true
ValidateFormatting: true
Artifacts:
- name: azure-ai-personalizer
safeName: azureaipersonalizer

Просмотреть файл

@ -24,6 +24,5 @@ extends:
parameters:
ServiceDirectory: ${{ parameters.Service }}
BuildTargetingString: "*"
ValidateFormatting: true
TestProxy: true
TestTimeOutInMinutes: 180

Просмотреть файл

@ -1,2 +1,3 @@
[tool.azure-sdk-build]
pyright = false
black = true

Просмотреть файл

@ -30,7 +30,6 @@ extends:
parameters:
TestProxy: true
ServiceDirectory: tables
ValidateFormatting: true
Artifacts:
- name: azure-data-tables
safeName: azuredatatables

Просмотреть файл

@ -45,7 +45,6 @@ extends:
parameters:
oneESTemplateTag: ${{ parameters.oneESTemplateTag }}
ServiceDirectory: template
ValidateFormatting: true
TestProxy: true
Artifacts:
- name: azure-template

Просмотреть файл

@ -35,9 +35,10 @@ IGNORE_PACKAGES = [
"azure-template",
]
MUST_RUN_ENVS = [
"bandit"
]
MUST_RUN_ENVS = ["bandit"]
# all of our checks default to ON, other than the below
CHECK_DEFAULTS = {"black": False}
def is_check_enabled(package_path: str, check: str, default: Any = True) -> bool:
"""
@ -81,7 +82,8 @@ def filter_tox_environment_string(namespace_argument: str, package_path: str) ->
filtered_set = []
for tox_env in [env.strip().lower() for env in tox_envs]:
if is_check_enabled(package_path, tox_env, True) or tox_env in MUST_RUN_ENVS:
check_enabled = is_check_enabled(package_path, tox_env, CHECK_DEFAULTS.get(tox_env, True))
if check_enabled or tox_env in MUST_RUN_ENVS:
filtered_set.append(tox_env)
return ",".join(filtered_set)

Просмотреть файл

@ -36,7 +36,6 @@ extends:
parameters:
ServiceDirectory: core
BuildTargetingString: "*"
ValidateFormatting: true
TestProxy: false
TestTimeoutInMinutes: 120
Artifacts: