Skip to content

Commit 62e4123

Browse files
authored
{CI} Fix static analysis (Azure#6509)
* Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * update * Empty * Update azure-pipelines.yml * Update azdev_setup.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Empty * update * modify containerapp * update * Update azdev_style_check.py * Update azdev_style_check.py * Update azdev_style_check.py * update * update * Delete azdev_style_check.py * Update test_source.py * Update azdev_linter_style.py * Update __init__.py * todo * update * update * Update __init__.py * Update azure-pipelines.yml * update * update * Update azdev_linter_style.py * update
1 parent e3096d6 commit 62e4123

6 files changed

+150
-232
lines changed

.flake8

+14-8
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22
max-line-length = 120
33
max-complexity = 10
44
ignore =
5-
E501, # line too long, it is covered by pylint
6-
E722, # bare except, bad practice, to be removed in the future
7-
F401, # imported but unused, too many violations, to be removed in the future
8-
F811, # redefinition of unused, to be removed in the future
9-
C901 # code flow is too complex, too many violations, to be removed in the future
10-
W503 # line break before binary operator effect on readability is subjective
11-
W504 # line break after binary operator effect on readability is subjective
12-
5+
# line too long, it is covered by pylint
6+
E501
7+
# bare except, bad practice, to be removed in the future
8+
E722
9+
# imported but unused, too many violations, to be removed in the future
10+
F401
11+
# redefinition of unused, to be removed in the future
12+
F811
13+
# code flow is too complex, too many violations, to be removed in the future
14+
C901
15+
# line break before binary operator effect on readability is subjective
16+
W503
17+
# line break after binary operator effect on readability is subjective
18+
W504
1319
exclude =
1420
*/vendored_sdks
1521
docs

azure-pipelines.yml

+30-18
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,6 @@ jobs:
6767
source ./env/bin/activate
6868
azdev verify license
6969
70-
- job: StaticAnalysis
71-
displayName: "Static Analysis"
72-
pool:
73-
name: 'pool-ubuntu-2004'
74-
steps:
75-
- task: UsePythonVersion@0
76-
displayName: 'Use Python 3.6'
77-
inputs:
78-
versionSpec: 3.6
79-
- bash: pip install wheel==0.30.0 pylint==1.9.5 flake8==3.5.0 requests
80-
displayName: 'Install wheel, pylint, flake8, requests'
81-
- bash: python scripts/ci/source_code_static_analysis.py
82-
displayName: "Static Analysis"
83-
8470
- job: IndexVerify
8571
displayName: "Verify Extensions Index"
8672
pool:
@@ -131,9 +117,10 @@ jobs:
131117
ADO_PULL_REQUEST_LATEST_COMMIT: HEAD
132118
ADO_PULL_REQUEST_TARGET_BRANCH: $(System.PullRequest.TargetBranch)
133119
134-
- job: LintModifiedExtensions
135-
displayName: "CLI Linter on Modified Extensions"
120+
- job: AzdevStyleModifiedExtensions
121+
displayName: "azdev style on Modified Extensions"
136122
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
123+
continueOnError: true
137124
pool:
138125
name: 'pool-ubuntu-2004'
139126
steps:
@@ -149,8 +136,33 @@ jobs:
149136
# overwrite the default AZURE_EXTENSION_DIR set by ADO
150137
AZURE_EXTENSION_DIR=~/.azure/cliextensions az --version
151138
152-
AZURE_EXTENSION_DIR=~/.azure/cliextensions python scripts/ci/verify_linter.py
153-
displayName: "CLI Linter on Modified Extension"
139+
AZURE_EXTENSION_DIR=~/.azure/cliextensions python scripts/ci/azdev_linter_style.py --type style
140+
displayName: "azdev style on Modified Extensions"
141+
env:
142+
ADO_PULL_REQUEST_LATEST_COMMIT: HEAD
143+
ADO_PULL_REQUEST_TARGET_BRANCH: $(System.PullRequest.TargetBranch)
144+
145+
- job: AzdevLinterModifiedExtensions
146+
displayName: "azdev linter on Modified Extensions"
147+
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
148+
pool:
149+
name: 'pool-ubuntu-2004'
150+
steps:
151+
- task: UsePythonVersion@0
152+
displayName: 'Use Python 3.11'
153+
inputs:
154+
versionSpec: 3.11
155+
- template: .azure-pipelines/templates/azdev_setup.yml
156+
- bash: |
157+
#!/usr/bin/env bash
158+
set -ev
159+
source ./env/bin/activate
160+
# overwrite the default AZURE_EXTENSION_DIR set by ADO
161+
AZURE_EXTENSION_DIR=~/.azure/cliextensions az --version
162+
163+
# TODO: remove --type linter once all extensions are fixed
164+
AZURE_EXTENSION_DIR=~/.azure/cliextensions python scripts/ci/azdev_linter_style.py --type linter
165+
displayName: "azdev linter on Modified Extensions"
154166
env:
155167
ADO_PULL_REQUEST_LATEST_COMMIT: HEAD
156168
ADO_PULL_REQUEST_TARGET_BRANCH: $(System.PullRequest.TargetBranch)

pylintrc

+45-30
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,58 @@
11
[MASTER]
22
ignore=tests,generated,vendored_sdks,privates
3+
ignore-patterns=test.*,azure_devops_build.*
4+
ignore-paths=.*/aaz
35
reports=no
46

57
[MESSAGES CONTROL]
68
# For all codes, run 'pylint --list-msgs' or go to 'https://pylint.readthedocs.io/en/latest/reference_guide/features.html'
9+
# cyclic-import: because of https://github.com/PyCQA/pylint/issues/850
10+
# import-outside-toplevel: Lazy import to improve performance
711
# locally-disabled: Warning locally suppressed using disable-msg
8-
# cyclic-import: Because of https://github.com/PyCQA/pylint/issues/850
912
# too-many-arguments: Due to the nature of the CLI many commands have large arguments set which reflect in large arguments set in corresponding methods.
10-
# import-outside-toplevel: Lazy import to improve performance
13+
# consider-using-f-string: str.format is still a Python standard
14+
# unspecified-encoding: Allow using the system encoding, instead of forcing utf-8 to avoid opening errors
1115
disable=
12-
missing-docstring,
13-
locally-disabled,
14-
fixme,
16+
arguments-out-of-order,
17+
bad-option-value,
18+
consider-using-with,
1519
cyclic-import,
16-
too-many-arguments,
17-
invalid-name,
1820
duplicate-code,
21+
fixme,
1922
import-outside-toplevel,
20-
too-many-lines
21-
22-
[TYPECHECK]
23-
# For Azure CLI extensions, we ignore some import errors as they'll be available in the environment of the CLI
24-
ignored-modules=azure,azure.cli,azure.cli.core,azure.cli.core.commands,knack,msrestazure,argcomplete,azure.cli.testsdk,isodate,OpenSSL
23+
inconsistent-return-statements,
24+
invalid-name,
25+
invalid-str-returned,
26+
locally-disabled,
27+
missing-docstring,
28+
missing-kwoa,
29+
no-member,
30+
no-value-for-parameter,
31+
raise-missing-from,
32+
subprocess-run-check,
33+
super-with-arguments,
34+
too-many-arguments,
35+
too-many-function-args,
36+
too-many-lines,
37+
using-constant-test,
38+
wrong-import-order,
39+
consider-using-f-string,
40+
unspecified-encoding,
41+
use-maxsplit-arg,
42+
arguments-renamed,
43+
consider-using-in,
44+
use-dict-literal,
45+
consider-using-dict-items,
46+
consider-using-enumerate,
47+
redundant-u-string-prefix,
48+
raising-bad-type,
49+
unused-private-member,
50+
used-before-assignment,
51+
# These rules were added in Pylint >= 2.12, disable them to avoid making retroactive change
52+
missing-timeout,
53+
superfluous-parens,
54+
implicit-str-concat,
55+
unnecessary-dunder-call,
2556

2657
[FORMAT]
2758
max-line-length=120
@@ -35,24 +66,8 @@ init-import=yes
3566
max-locals=25
3667
# Maximum number of branch for function / method body
3768
max-branches=20
69+
# Temporally disable this check as inline disable is not working, see https://github.com/pylint-dev/pylint/issues/8806
70+
max-statements=500
3871

3972
[SIMILARITIES]
4073
min-similarity-lines=10
41-
42-
[BASIC]
43-
# Naming hints based on PEP 8 (https://www.python.org/dev/peps/pep-0008/#naming-conventions).
44-
# Consider these guidelines and not hard rules. Read PEP 8 for more details.
45-
46-
# The invalid-name checker must be **enabled** for these hints to be used.
47-
include-naming-hint=yes
48-
49-
module-name-hint=lowercase (keep short; underscores are discouraged)
50-
const-name-hint=UPPER_CASE_WITH_UNDERSCORES
51-
class-name-hint=CapitalizedWords
52-
class-attribute-name-hint=lower_case_with_underscores
53-
attr-name-hint=lower_case_with_underscores
54-
method-name-hint=lower_case_with_underscores
55-
function-name-hint=lower_case_with_underscores
56-
argument-name-hint=lower_case_with_underscores
57-
variable-name-hint=lower_case_with_underscores
58-
inlinevar-name-hint=lower_case_with_underscores (short is OK)

scripts/ci/verify_linter.py scripts/ci/azdev_linter_style.py

+50-25
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,27 @@
44
# --------------------------------------------------------------------------------------------
55

66
"""
7-
This script is used to verify linter on extensions.
7+
This script is used to run azdev linter and azdev style on extensions.
88
99
It's only working on ADO by default. If want to run locally,
1010
please update the target branch/commit to find diff in function find_modified_files_against_master_branch()
1111
"""
12-
13-
import os
1412
import json
15-
from subprocess import check_output, check_call
16-
from pkg_resources import parse_version
13+
import logging
14+
import os
15+
from subprocess import check_call, check_output
1716

1817
import service_name
18+
from pkg_resources import parse_version
1919

20+
logger = logging.getLogger(__name__)
21+
logger.setLevel(logging.DEBUG)
22+
ch = logging.StreamHandler()
23+
ch.setLevel(logging.DEBUG)
24+
logger.addHandler(ch)
2025

2126
def separator_line():
22-
print('-' * 100)
27+
logger.info('-' * 100)
2328

2429

2530
class ModifiedFilesNotAllowedError(Exception):
@@ -50,7 +55,7 @@ def __init__(self, extension_name):
5055

5156
@staticmethod
5257
def _cmd(cmd):
53-
print(cmd)
58+
logger.info(cmd)
5459
check_call(cmd, shell=True)
5560

5661
def add_from_url(self, url):
@@ -66,7 +71,7 @@ def __init__(self, extension_name):
6671

6772
@staticmethod
6873
def _cmd(cmd):
69-
print(cmd)
74+
logger.info(cmd)
7075
check_call(cmd, shell=True)
7176

7277
def add_from_code(self):
@@ -78,6 +83,9 @@ def remove(self):
7883
def linter(self):
7984
self._cmd('azdev linter --include-whl-extensions {}'.format(self.extension_name))
8085

86+
def style(self):
87+
self._cmd('azdev style {}'.format(self.extension_name))
88+
8189
def build(self):
8290
pass
8391

@@ -91,17 +99,17 @@ def find_modified_files_against_master_branch():
9199
ado_pr_target_branch = 'origin/' + os.environ.get('ADO_PULL_REQUEST_TARGET_BRANCH')
92100

93101
separator_line()
94-
print('pull request target branch:', ado_pr_target_branch)
102+
logger.info('pull request target branch: %s', ado_pr_target_branch)
95103

96104
cmd = 'git --no-pager diff --name-only --diff-filter=ACMRT {} -- src/'.format(ado_pr_target_branch)
97105
files = check_output(cmd.split()).decode('utf-8').split('\n')
98106
files = [f for f in files if len(f) > 0]
99107

100108
if files:
101-
print('modified files:')
109+
logger.info('modified files:')
102110
separator_line()
103111
for f in files:
104-
print(f)
112+
logger.info(f)
105113

106114
return files
107115

@@ -131,10 +139,10 @@ def contain_extension_code(files):
131139
return False
132140

133141

134-
def linter_on_external_extension(index_json):
142+
def azdev_on_external_extension(index_json, azdev_type):
135143
"""
136144
Check if the modified metadata items in index.json refer to the extension in repo.
137-
If not, az extension linter on wheel. Otherwise skip it.
145+
If not, az extension check on wheel. Otherwise skip it.
138146
"""
139147

140148
public_extensions = json.loads(check_output('az extension list-available -d', shell=True))
@@ -160,15 +168,20 @@ def linter_on_external_extension(index_json):
160168
az_extension.add_from_url(latest_entry['downloadUrl'])
161169

162170
azdev_extension = AzdevExtensionHelper(name)
163-
azdev_extension.linter()
164-
165-
print('Checking service name for external extensions')
171+
if azdev_type in ['all', 'linter']:
172+
azdev_extension.linter()
173+
# TODO:
174+
# azdev style support external extension
175+
# azdev test support external extension
176+
# azdev_extension.style()
177+
178+
logger.info('Checking service name for external extensions')
166179
service_name.check()
167180

168181
az_extension.remove()
169182

170183

171-
def linter_on_internal_extension(modified_files):
184+
def azdev_on_internal_extension(modified_files, azdev_type):
172185
extension_names = set()
173186

174187
for f in modified_files:
@@ -178,31 +191,43 @@ def linter_on_internal_extension(modified_files):
178191

179192
if not extension_names:
180193
separator_line()
181-
print('no extension source code modified, no extension needs to be linter')
194+
logger.info('no extension source code modified, no extension needs to be checked')
182195

183196
for name in extension_names:
184197
separator_line()
185198

186199
azdev_extension = AzdevExtensionHelper(name)
187200
azdev_extension.add_from_code()
188-
azdev_extension.linter()
201+
if azdev_type in ['all', 'linter']:
202+
azdev_extension.linter()
203+
if azdev_type in ['all', 'style']:
204+
azdev_extension.style()
189205

190-
print('Checking service name for internal extensions')
206+
logger.info('Checking service name for internal extensions')
191207
service_name.check()
192208

193209
azdev_extension.remove()
194210

195211

196212
def main():
213+
import argparse
214+
parser = argparse.ArgumentParser(description='azdev linter and azdev style on modified extensions')
215+
parser.add_argument('--type',
216+
type=str,
217+
help='Control whether azdev linter, azdev style, azdev test needs to be run. '
218+
'Supported values: linter, style, test, all, all is the default.', default='all')
219+
args = parser.parse_args()
220+
azdev_type = args.type
221+
logger.info('azdev type: %s', azdev_type)
197222
modified_files = find_modified_files_against_master_branch()
198223

199224
if len(modified_files) == 1 and contain_index_json(modified_files):
200225
# Scenario 1.
201226
# This scenarios is for modify index.json only.
202227
# If the modified metadata items refer to the extension code exits in this repo, PR is be created via Pipeline.
203228
# If the modified metadata items refer to the extension code doesn't exist, PR is created from Service Team.
204-
# We try to verify linter on it.
205-
linter_on_external_extension(modified_files[0])
229+
# We try to run azdev linter and azdev style on it.
230+
azdev_on_external_extension(modified_files[0], azdev_type)
206231
else:
207232
# modified files contain more than one file
208233

@@ -211,16 +236,16 @@ def main():
211236
if contain_index_json(modified_files):
212237
raise ModifiedFilesNotAllowedError()
213238

214-
linter_on_internal_extension(modified_files)
239+
azdev_on_internal_extension(modified_files, azdev_type)
215240
else:
216241
separator_line()
217-
print('no extension source code modified, no extension needs to be linter')
242+
logger.info('no extension source code modified, no extension needs to be checked')
218243
separator_line()
219244

220245

221246
if __name__ == '__main__':
222247
try:
223248
main()
224249
except ModifiedFilesNotAllowedError as e:
225-
print(e)
250+
logger.error(e)
226251
exit(1)

0 commit comments

Comments
 (0)