azdev 0.1.87__tar.gz → 0.1.88__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {azdev-0.1.87 → azdev-0.1.88}/HISTORY.rst +3 -0
  2. {azdev-0.1.87/azdev.egg-info → azdev-0.1.88}/PKG-INFO +4 -1
  3. {azdev-0.1.87 → azdev-0.1.88}/azdev/__init__.py +1 -1
  4. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/linter.py +93 -77
  5. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/regex.py +10 -0
  6. {azdev-0.1.87 → azdev-0.1.88/azdev.egg-info}/PKG-INFO +4 -1
  7. {azdev-0.1.87 → azdev-0.1.88}/LICENSE +0 -0
  8. {azdev-0.1.87 → azdev-0.1.88}/MANIFEST.in +0 -0
  9. {azdev-0.1.87 → azdev-0.1.88}/README.md +0 -0
  10. {azdev-0.1.87 → azdev-0.1.88}/README.rst +0 -0
  11. {azdev-0.1.87 → azdev-0.1.88}/azdev/__main__.py +0 -0
  12. {azdev-0.1.87 → azdev-0.1.88}/azdev/commands.py +0 -0
  13. {azdev-0.1.87 → azdev-0.1.88}/azdev/completer.py +0 -0
  14. {azdev-0.1.87 → azdev-0.1.88}/azdev/config/__init__.py +0 -0
  15. {azdev-0.1.87 → azdev-0.1.88}/azdev/config/cli.flake8 +0 -0
  16. {azdev-0.1.87 → azdev-0.1.88}/azdev/config/cli_pylintrc +0 -0
  17. {azdev-0.1.87 → azdev-0.1.88}/azdev/config/ext.flake8 +0 -0
  18. {azdev-0.1.87 → azdev-0.1.88}/azdev/config/ext_pylintrc +0 -0
  19. {azdev-0.1.87 → azdev-0.1.88}/azdev/help.py +0 -0
  20. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/HISTORY.rst +0 -0
  21. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/README.rst +0 -0
  22. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/_client_factory.py +0 -0
  23. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/_help.py +0 -0
  24. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/_params.py +0 -0
  25. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/_validators.py +0 -0
  26. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/azext_metadata.json +0 -0
  27. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/blank__init__.py +0 -0
  28. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/commands.py +0 -0
  29. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/custom.py +0 -0
  30. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/module__init__.py +0 -0
  31. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/pkg_declare__init__.py +0 -0
  32. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/setup.cfg +0 -0
  33. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/setup.py +0 -0
  34. {azdev-0.1.87 → azdev-0.1.88}/azdev/mod_templates/test_service_scenario.py +0 -0
  35. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/__init__.py +0 -0
  36. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/breaking_change/__init__.py +0 -0
  37. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/breaking_change/markdown_template.jinja2 +0 -0
  38. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/__init__.py +0 -0
  39. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/_macros.j2 +0 -0
  40. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/cmdcov.py +0 -0
  41. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/component.css +0 -0
  42. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/component.js +0 -0
  43. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/favicon.ico +0 -0
  44. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/index.j2 +0 -0
  45. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/index2.j2 +0 -0
  46. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/cmdcov/module.j2 +0 -0
  47. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/code_gen.py +0 -0
  48. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/command_change/__init__.py +0 -0
  49. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/command_change/custom.py +0 -0
  50. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/command_change/util.py +0 -0
  51. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/constant.py +0 -0
  52. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/extensions/__init__.py +0 -0
  53. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/extensions/util.py +0 -0
  54. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/extensions/version_upgrade.py +0 -0
  55. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/help/__init__.py +0 -0
  56. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/help/refdoc/__init__.py +0 -0
  57. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/help/refdoc/conf.py +0 -0
  58. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/legal.py +0 -0
  59. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/__init__.py +0 -0
  60. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/pylint_checkers/__init__.py +0 -0
  61. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/pylint_checkers/show_command.py +0 -0
  62. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rule_decorators.py +0 -0
  63. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/__init__.py +0 -0
  64. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/ci_exclusions.yml +0 -0
  65. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/command_coverage_rules.py +0 -0
  66. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/command_group_rules.py +0 -0
  67. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/command_rules.py +0 -0
  68. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/help_rules.py +0 -0
  69. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/linter_exclusions.yml +0 -0
  70. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/rules/parameter_rules.py +0 -0
  71. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/linter/util.py +0 -0
  72. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/performance.py +0 -0
  73. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/pypi.py +0 -0
  74. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/python_sdk.py +0 -0
  75. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/resource.py +0 -0
  76. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/secret.py +0 -0
  77. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/setup.py +0 -0
  78. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/statistics/__init__.py +0 -0
  79. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/statistics/util.py +0 -0
  80. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/style.py +0 -0
  81. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/testtool/__init__.py +0 -0
  82. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/testtool/incremental_strategy.py +0 -0
  83. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/testtool/profile_context.py +0 -0
  84. {azdev-0.1.87 → azdev-0.1.88}/azdev/operations/testtool/pytest_runner.py +0 -0
  85. {azdev-0.1.87 → azdev-0.1.88}/azdev/params.py +0 -0
  86. {azdev-0.1.87 → azdev-0.1.88}/azdev/transformers.py +0 -0
  87. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/__init__.py +0 -0
  88. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/command.py +0 -0
  89. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/config.py +0 -0
  90. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/const.py +0 -0
  91. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/display.py +0 -0
  92. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/git_util.py +0 -0
  93. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/path.py +0 -0
  94. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/pypi.py +0 -0
  95. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/testing.py +0 -0
  96. {azdev-0.1.87 → azdev-0.1.88}/azdev/utilities/tools.py +0 -0
  97. {azdev-0.1.87 → azdev-0.1.88}/azdev.egg-info/SOURCES.txt +0 -0
  98. {azdev-0.1.87 → azdev-0.1.88}/azdev.egg-info/dependency_links.txt +0 -0
  99. {azdev-0.1.87 → azdev-0.1.88}/azdev.egg-info/entry_points.txt +0 -0
  100. {azdev-0.1.87 → azdev-0.1.88}/azdev.egg-info/requires.txt +0 -0
  101. {azdev-0.1.87 → azdev-0.1.88}/azdev.egg-info/top_level.txt +0 -0
  102. {azdev-0.1.87 → azdev-0.1.88}/pyproject.toml +0 -0
  103. {azdev-0.1.87 → azdev-0.1.88}/setup.cfg +0 -0
  104. {azdev-0.1.87 → azdev-0.1.88}/setup.py +0 -0
@@ -2,6 +2,9 @@
2
2
 
3
3
  Release History
4
4
  ===============
5
+ 0.1.88
6
+ * `azdev cmdcov`: Fix incorrect detection of code changes as new commands
7
+
5
8
  0.1.87
6
9
  ++++++
7
10
  * `azdev linter`: Fix repo path failed when `detect_new_command`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azdev
3
- Version: 0.1.87
3
+ Version: 0.1.88
4
4
  Summary: Microsoft Azure CLI Developer Tools
5
5
  Home-page: https://github.com/Azure/azure-cli-dev-tools
6
6
  Author: Microsoft Corporation
@@ -148,6 +148,9 @@ License
148
148
 
149
149
  Release History
150
150
  ===============
151
+ 0.1.88
152
+ * `azdev cmdcov`: Fix incorrect detection of code changes as new commands
153
+
151
154
  0.1.87
152
155
  ++++++
153
156
  * `azdev linter`: Fix repo path failed when `detect_new_command`.
@@ -4,4 +4,4 @@
4
4
  # license information.
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __VERSION__ = '0.1.87'
7
+ __VERSION__ = '0.1.88'
@@ -11,6 +11,7 @@ import inspect
11
11
  import os
12
12
  import re
13
13
  from pkgutil import iter_modules
14
+ from typing import List, Tuple
14
15
  import yaml
15
16
  from knack.log import get_logger
16
17
 
@@ -19,6 +20,7 @@ from azdev.operations.regex import (
19
20
  search_argument,
20
21
  search_argument_context,
21
22
  search_command,
23
+ search_deleted_command,
22
24
  search_command_group)
23
25
  from azdev.utilities import diff_branches_detail, diff_branch_file_patch
24
26
  from azdev.utilities.path import get_cli_repo_path, get_ext_repo_paths
@@ -222,86 +224,100 @@ class Linter: # pylint: disable=too-many-public-methods, too-many-instance-attr
222
224
  all_tested_command = self._detect_tested_command(diff_index)
223
225
  return self._run_parameter_test_coverage(parameters, all_tested_command)
224
226
 
225
- # pylint: disable=too-many-locals, too-many-nested-blocks, too-many-branches, too-many-statements
226
- def _detect_new_command(self, diff_index):
227
- """
228
- exclude_comands: List[str]
229
- exclude_parameters: List[tuple[str, str]]
230
- commands: List[str]
231
- parameters: List[str, List[str]]
232
- """
227
+ def _get_exclusions(self):
228
+ _exclude_commands = set()
229
+ _exclude_parameters = set()
230
+ for command, details in self.exclusions.items():
231
+ if 'parameters' in details:
232
+ for param, rules in details['parameters'].items():
233
+ if 'missing_parameter_test_coverage' in rules['rule_exclusions']:
234
+ _exclude_parameters.add((command, param))
235
+ if 'rule_exclusions' in details and 'missing_command_test_coverage' in details['rule_exclusions']:
236
+ _exclude_commands.add(command)
237
+ _logger.debug('exclude_parameters: %s', _exclude_parameters)
238
+ _logger.debug('exclude_comands: %s', _exclude_commands)
239
+ return _exclude_commands, _exclude_parameters
240
+
241
+ def _split_path(self, path: str):
242
+ parts = path.rsplit('/', maxsplit=1)
243
+ return parts if len(parts) == 2 else ('', parts[0])
244
+
245
+ def _read_blob_lines(self, blob):
246
+ return blob.data_stream.read().decode("utf-8").splitlines(True) if blob else []
247
+
248
+ def _get_line_number(self, lines: List[str], row_num: int, pattern: str):
249
+ offset = -1
250
+ while row_num > 0:
251
+ row_num -= 1
252
+ match = re.findall(pattern, lines[row_num])
253
+ offset += 1
254
+ if match:
255
+ return int(match[0]) + offset
256
+ return -1
257
+
258
+ def _extract_parameters(self, lines, current_lines, _exclude_commands, _exclude_parameters, parameters):
259
+ for row_num, line in enumerate(lines):
260
+ params, param_name = search_argument(line)
261
+ if params:
262
+ idx = self._get_line_number(lines, row_num, r'--- (\d+),(?:\d+) ----')
263
+ commands = search_argument_context(idx, current_lines)
264
+ for cmd in commands:
265
+ if cmd not in _exclude_commands and (cmd, param_name) not in _exclude_parameters:
266
+ parameters.append((cmd, params))
267
+ _logger.debug('Detected parameter: [%s, %s]', cmd, params)
268
+ return parameters
269
+
270
+ def _extract_commands(self, lines, original_lines, current_lines, added_commands,
271
+ deleted_commands, _exclude_commands, yellow_color):
272
+ for row_num, line in enumerate(lines):
273
+ added_command = search_command(line)
274
+ deleted_command = search_deleted_command(line)
275
+
276
+ if added_command:
277
+ idx = self._get_line_number(lines, row_num, r'--- (\d+),(?:\d+) ----')
278
+ cmd = search_command_group(idx, current_lines, added_command)
279
+ if cmd:
280
+ if cmd in _exclude_commands:
281
+ _logger.warning('%sCommand %s not tested and excluded in linter_exclusions.yml',
282
+ yellow_color, cmd)
283
+ else:
284
+ added_commands.add(cmd)
285
+
286
+ elif deleted_command:
287
+ idx = self._get_line_number(lines, row_num, r'\*\*\* (\d+),(?:\d+) \*\*\*\*')
288
+ cmd = search_command_group(idx, original_lines, deleted_command)
289
+ if cmd:
290
+ deleted_commands.add(cmd)
291
+ return added_commands, deleted_commands
292
+
293
+ def _detect_new_command(self, diff_index: List) -> Tuple[List[str], List[Tuple[str, str]]]:
233
294
  YELLOW = '\x1b[33m'
234
- parameters = []
235
- commands = []
236
- lines = []
237
- exclude_comands = []
238
- exclude_parameters = []
239
- for c, v in self.exclusions.items():
240
- if 'parameters' in v:
241
- for p, r in v['parameters'].items():
242
- if 'missing_parameter_test_coverage' in r['rule_exclusions']:
243
- exclude_parameters.append((c, p))
244
- if 'rule_exclusions' in v:
245
- if 'missing_command_test_coverage' in v['rule_exclusions']:
246
- exclude_comands.append(c)
247
- _logger.debug('exclude_parameters: %s', exclude_parameters)
248
- _logger.debug('exclude_comands: %s', exclude_comands)
295
+ _exclude_commands, _exclude_parameters = self._get_exclusions()
296
+ added_commands, deleted_commands, parameters = set(), set(), []
249
297
 
250
298
  for diff in diff_index:
251
- filename = diff.a_path.split('/')[-1]
252
- if 'params' in filename or 'commands' in filename:
253
- lines = list(
254
- context_diff(diff.a_blob.data_stream.read().decode("utf-8").splitlines(True) if diff.a_blob else [],
255
- diff.b_blob.data_stream.read().decode("utf-8").splitlines(True) if diff.b_blob else [],
256
- 'Original', 'Current'))
257
- for row_num, line in enumerate(lines):
258
- if 'params.py' in filename:
259
- params, param_name = search_argument(line)
260
- if params:
261
- offset = -1
262
- while row_num > 0:
263
- row_num -= 1
264
- # Match row num '--- 156,163 ----'
265
- sub_pattern = r'--- (\d{0,}),(?:\d{0,}) ----'
266
- idx = re.findall(sub_pattern, lines[row_num])
267
- offset += 1
268
- if idx:
269
- idx = int(idx[0]) + offset
270
- break
271
- with open(os.path.join(self.git_repo, diff.a_path), encoding='utf-8') as f:
272
- param_lines = f.readlines()
273
- cmds = search_argument_context(idx, param_lines)
274
- for cmd in cmds:
275
- if cmd not in exclude_comands and \
276
- not list(filter(lambda x, c=cmd, p=param_name: c in x[0] and p in x[1], exclude_parameters)): # pylint: disable=line-too-long
277
- parameters.append([cmd, params])
278
- else:
279
- print('%sCommand [%s, %s] not test and exclude in linter_exclusions.yml' % (
280
- YELLOW, cmd, params))
281
-
282
- if 'commands.py' in filename:
283
- command = search_command(line)
284
- if command:
285
- offset = -1
286
- while row_num > 0:
287
- row_num -= 1
288
- # Match row num '--- 156,163 ----'
289
- sub_pattern = r'--- (\d{0,}),(?:\d{0,}) ----'
290
- idx = re.findall(sub_pattern, lines[row_num])
291
- offset += 1
292
- if idx:
293
- idx = int(idx[0]) + offset
294
- break
295
- with open(os.path.join(self.git_repo, diff.a_path), encoding='utf-8') as f:
296
- cmd_lines = f.readlines()
297
- cmd = search_command_group(idx, cmd_lines, command)
298
- if cmd:
299
- if cmd in exclude_comands:
300
- print('%sCommand %s not test and exclude in linter_exclusions.yml' % (YELLOW, cmd))
301
- else:
302
- commands.append(cmd)
303
- _logger.debug('New add parameters: %s', parameters)
304
- _logger.debug('New add commands: %s', commands)
299
+ _, filename = self._split_path(diff.a_path)
300
+ if not any(key in filename for key in ('params', 'commands')):
301
+ continue
302
+
303
+ original_lines = self._read_blob_lines(diff.a_blob)
304
+ current_lines = self._read_blob_lines(diff.b_blob)
305
+ lines = list(context_diff(original_lines, current_lines, 'Original', 'Current'))
306
+
307
+ if 'params.py' in filename:
308
+ parameters = self._extract_parameters(lines, current_lines, _exclude_commands,
309
+ _exclude_parameters, parameters)
310
+
311
+ if 'commands.py' in filename:
312
+ added_commands, deleted_commands = self._extract_commands(lines, original_lines, current_lines,
313
+ added_commands, deleted_commands,
314
+ _exclude_commands, YELLOW)
315
+
316
+ commands = list(added_commands - deleted_commands)
317
+ _logger.debug('New parameters: %s', parameters)
318
+ _logger.debug('Added commands: %s', added_commands)
319
+ _logger.debug('Deleted commands: %s', deleted_commands)
320
+ _logger.debug('Final commands: %s', commands)
305
321
  return commands, parameters
306
322
 
307
323
  def _detect_tested_command(self, diff_index):
@@ -162,3 +162,13 @@ def search_command(line):
162
162
  if ref:
163
163
  command = ref[0].split(',')[0].strip("'")
164
164
  return command
165
+
166
+
167
+ def search_deleted_command(line):
168
+ command = ''
169
+ # Match `- g.*command(xxx)`
170
+ pattern = r'\-\s+g.(?:\w+)?command\((.*)\)'
171
+ ref = re.findall(pattern, line)
172
+ if ref:
173
+ command = ref[0].split(',')[0].strip("'")
174
+ return command
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azdev
3
- Version: 0.1.87
3
+ Version: 0.1.88
4
4
  Summary: Microsoft Azure CLI Developer Tools
5
5
  Home-page: https://github.com/Azure/azure-cli-dev-tools
6
6
  Author: Microsoft Corporation
@@ -148,6 +148,9 @@ License
148
148
 
149
149
  Release History
150
150
  ===============
151
+ 0.1.88
152
+ * `azdev cmdcov`: Fix incorrect detection of code changes as new commands
153
+
151
154
  0.1.87
152
155
  ++++++
153
156
  * `azdev linter`: Fix repo path failed when `detect_new_command`.
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