1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import re
import os
import subprocess
oldArguments = []
newArguments = []
allowedMissingArguments = {}
allowedMissingArguments['devops extension uninstall'] = ['--extension-name', '--publisher-name']
allowedMissingArguments['devops extension install'] = ['--extension-name', '--publisher-name']
allowedMissingArguments['devops extension enable'] = ['--extension-name', '--publisher-name']
allowedMissingArguments['devops extension disable'] = ['--extension-name', '--publisher-name']
allowedMissingArguments['devops extension show'] = ['--extension-name', '--publisher-name']
allowedNewMandatoryArguments = {}
allowedNewMandatoryArguments['devops extension uninstall'] = ['--extension-id', '--publisher-id']
allowedNewMandatoryArguments['devops extension install'] = ['--extension-id', '--publisher-id']
allowedNewMandatoryArguments['devops extension enable'] = ['--extension-id', '--publisher-id']
allowedNewMandatoryArguments['devops extension disable'] = ['--extension-id', '--publisher-id']
allowedNewMandatoryArguments['devops extension show'] = ['--extension-id', '--publisher-id']
# Do not compare these commands
ignoreCommands = []
class Arguments(dict):
def __init__(self, command, name, isRequired):
self.command = command
self.name = name
self.isRequired = isRequired
dict.__init__(self,command = command, name = name, isRequired = isRequired)
def extractArgumentsFromCommand(command):
print('running extractArgumentsFromCommand for ' + command)
argumentList = []
commandExtended = 'az ' + command + ' -h'
help_text = subprocess.run(commandExtended.split(' '), shell=True, stdout=subprocess.PIPE)
print('help text for ' + command)
print(help_text)
if " is in preview" in str(help_text):
return argumentList
regexReesult = re.search('Arguments(.*)Global Arguments',str(help_text))
result = regexReesult.group(1)
argumentLines = result.split('\\r\\n')
for argumentLine in argumentLines:
argumentLineSplits = argumentLine.split(" : ")
if len(argumentLineSplits) > 1 and ' : ' in argumentLine:
isRequired = False
if '[Required]' in argumentLineSplits[0]:
isRequired = True
names = argumentLineSplits[0].replace('[Required]','').strip().split(' ')
for name in names:
argument = Arguments(command, name, isRequired)
argumentList.append(argument)
return argumentList
# remove azure-devops extension from index (if installed)
subprocess.run(['az', 'extension', 'remove', '-n', 'azure-devops'], shell=True)
# install extension from index
subprocess.run(['az', 'extension', 'add', '-n', 'azure-devops'], shell=True)
# Check the installed extensions
subprocess.run(['az', 'extension', 'list'], shell=True)
# add extension path to sys.path so that we can get all the commands
import sys
from azure.cli.core.extension import get_extension_path
# Make sure that the extension install directory is on sys.path so that dependencies can be found.
extensionPath = get_extension_path('azure-devops')
sys.path.append(extensionPath)
# loading commands from code
from azure.cli.core.mock import DummyCli
from azext_devops import DevCommandsLoader
cli_ctx = DummyCli()
loader = DevCommandsLoader(cli_ctx)
loader.load_command_table(None)
for command in loader.command_table:
oldArguments.extend(extractArgumentsFromCommand(command))
print('Unload extension (loaded from index).')
# uninstall extension loaded from index
subprocess.run(['az', 'extension', 'remove', '-n', 'azure-devops'], shell=True, stdout=subprocess.PIPE)
# search and install extension from given path
def findExtension():
for p, d, f in os.walk('.'):
for file in f:
if file.endswith('.whl'):
return os.path.join(p, file)
newExtensionLocation = findExtension()
print('Install extension (loaded from current code). Wheel path - {}'.format(newExtensionLocation))
subprocess.run(['az', 'extension', 'add', '--source', newExtensionLocation, '-y'], shell=True, stdout=subprocess.PIPE)
# Check the installed extensions
subprocess.run(['az', 'extension', 'list'], shell=True)
# get a set of old commands, we are not reusing the set from ext because we want to keep this clean
oldCommands = []
for oldArgument in oldArguments:
if oldArgument.command not in ignoreCommands:
if not (oldArgument.command in oldCommands):
oldCommands.append(oldArgument.command)
else:
print('Ignoring command.. ' + oldArgument.command)
# prepare argument set from new extension
for oldCommand in oldCommands:
print("Running extract for command: {}".format(oldCommand))
newArguments.extend(extractArgumentsFromCommand(oldCommand))
errorList = []
# make sure no new argument is mandatory
for newArgument in newArguments:
if newArgument.isRequired is True:
isNewMandatory = True
for oldArgument in oldArguments:
if oldArgument.command == newArgument.command and oldArgument.name == newArgument.name and oldArgument.isRequired is True:
isNewMandatory = False
break
if isNewMandatory is True:
allowedNewMandatoryArgumentsForCommand = allowedNewMandatoryArguments.get(newArgument.command, [])
if not newArgument.name in allowedNewMandatoryArgumentsForCommand:
errorList.append('\n' + 'New Mandatory argument found for command ' + newArgument.command + ' argument ' + newArgument.name)
# make sure no argument is removed
for oldArgument in oldArguments:
if oldArgument.command not in ignoreCommands:
isArgumentMissing = True
for newArgument in newArguments:
if oldArgument.name == newArgument.name and oldArgument.command == newArgument.command:
isArgumentMissing = False
break
if isArgumentMissing is True:
allowedMissingArgumetsForCommand = allowedMissingArguments.get(oldArgument.command, [])
if not oldArgument.name in allowedMissingArgumetsForCommand:
errorList.append('\n' + 'Argument missing for command ' + oldArgument.command + ' argument ' + oldArgument.name)
if len(errorList) > 0:
import sys
sys.stderr.write(' '.join(errorList))
raise Exception('Something is not correct')
|