Support module alias and rename validation. (#22675)
Cache git ls-tree output to speed up validation.
This commit is contained in:
parent
dd8d699981
commit
1f337b6421
1 changed files with 44 additions and 11 deletions
|
@ -205,7 +205,7 @@ class ModuleValidator(Validator):
|
||||||
'setup.ps1'
|
'setup.ps1'
|
||||||
))
|
))
|
||||||
|
|
||||||
def __init__(self, path, analyze_arg_spec=False, base_branch=None):
|
def __init__(self, path, analyze_arg_spec=False, base_branch=None, git_cache=None):
|
||||||
super(ModuleValidator, self).__init__()
|
super(ModuleValidator, self).__init__()
|
||||||
|
|
||||||
self.path = path
|
self.path = path
|
||||||
|
@ -215,6 +215,7 @@ class ModuleValidator(Validator):
|
||||||
self.analyze_arg_spec = analyze_arg_spec
|
self.analyze_arg_spec = analyze_arg_spec
|
||||||
|
|
||||||
self.base_branch = base_branch
|
self.base_branch = base_branch
|
||||||
|
self.git_cache = git_cache or GitCache()
|
||||||
|
|
||||||
self._python_module_override = False
|
self._python_module_override = False
|
||||||
|
|
||||||
|
@ -272,15 +273,11 @@ class ModuleValidator(Validator):
|
||||||
|
|
||||||
def _get_base_branch_module_path(self):
|
def _get_base_branch_module_path(self):
|
||||||
"""List all paths within lib/ansible/modules to try and match a moved module"""
|
"""List all paths within lib/ansible/modules to try and match a moved module"""
|
||||||
command = ['git', 'ls-tree', '-r', '--name-only', self.base_branch, 'lib/ansible/modules/']
|
return self.git_cache.base_module_paths.get(self.object_name)
|
||||||
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
stdout, stderr = p.communicate()
|
|
||||||
|
|
||||||
for path in stdout.splitlines():
|
def _has_alias(self):
|
||||||
if path.endswith('/%s' % self.object_name):
|
"""Return true if the module has any aliases."""
|
||||||
return path
|
return self.object_name in self.git_cache.head_aliased_modules
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_base_file(self):
|
def _get_base_file(self):
|
||||||
# In case of module moves, look for the original location
|
# In case of module moves, look for the original location
|
||||||
|
@ -300,6 +297,9 @@ class ModuleValidator(Validator):
|
||||||
return t.name
|
return t.name
|
||||||
|
|
||||||
def _is_new_module(self):
|
def _is_new_module(self):
|
||||||
|
if self._has_alias():
|
||||||
|
return False
|
||||||
|
|
||||||
return not self.object_name.startswith('_') and bool(self.base_branch) and not bool(self.base_module)
|
return not self.object_name.startswith('_') and bool(self.base_branch) and not bool(self.base_module)
|
||||||
|
|
||||||
def _check_interpreter(self, powershell=False):
|
def _check_interpreter(self, powershell=False):
|
||||||
|
@ -827,6 +827,9 @@ class ModuleValidator(Validator):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(ModuleValidator, self).validate()
|
super(ModuleValidator, self).validate()
|
||||||
|
|
||||||
|
if self.object_name.startswith('_') and os.path.islink(self.object_path):
|
||||||
|
return
|
||||||
|
|
||||||
# Blacklists -- these files are not checked
|
# Blacklists -- these files are not checked
|
||||||
if not frozenset((self.basename,
|
if not frozenset((self.basename,
|
||||||
self.name)).isdisjoint(self.BLACKLIST):
|
self.name)).isdisjoint(self.BLACKLIST):
|
||||||
|
@ -954,13 +957,15 @@ def main():
|
||||||
|
|
||||||
reports = OrderedDict()
|
reports = OrderedDict()
|
||||||
|
|
||||||
|
git_cache = GitCache(args.base_branch)
|
||||||
|
|
||||||
for module in args.modules:
|
for module in args.modules:
|
||||||
if os.path.isfile(module):
|
if os.path.isfile(module):
|
||||||
path = module
|
path = module
|
||||||
if args.exclude and args.exclude.search(path):
|
if args.exclude and args.exclude.search(path):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
with ModuleValidator(path, analyze_arg_spec=args.arg_spec,
|
with ModuleValidator(path, analyze_arg_spec=args.arg_spec,
|
||||||
base_branch=args.base_branch) as mv:
|
base_branch=args.base_branch, git_cache=git_cache) as mv:
|
||||||
mv.validate()
|
mv.validate()
|
||||||
reports.update(mv.report())
|
reports.update(mv.report())
|
||||||
|
|
||||||
|
@ -983,7 +988,7 @@ def main():
|
||||||
if args.exclude and args.exclude.search(path):
|
if args.exclude and args.exclude.search(path):
|
||||||
continue
|
continue
|
||||||
with ModuleValidator(path, analyze_arg_spec=args.arg_spec,
|
with ModuleValidator(path, analyze_arg_spec=args.arg_spec,
|
||||||
base_branch=args.base_branch) as mv:
|
base_branch=args.base_branch, git_cache=git_cache) as mv:
|
||||||
mv.validate()
|
mv.validate()
|
||||||
reports.update(mv.report())
|
reports.update(mv.report())
|
||||||
|
|
||||||
|
@ -993,6 +998,34 @@ def main():
|
||||||
sys.exit(Reporter.json(reports, warnings=args.warnings, output=args.output))
|
sys.exit(Reporter.json(reports, warnings=args.warnings, output=args.output))
|
||||||
|
|
||||||
|
|
||||||
|
class GitCache(object):
|
||||||
|
def __init__(self, base_branch):
|
||||||
|
self.base_branch = base_branch
|
||||||
|
|
||||||
|
self.base_tree = self._git(['ls-tree', '-r', '--name-only', self.base_branch, 'lib/ansible/modules/'])
|
||||||
|
self.head_tree = self._git(['ls-tree', '-r', '--name-only', 'HEAD', 'lib/ansible/modules/'])
|
||||||
|
|
||||||
|
self.base_module_paths = dict((os.path.basename(p), p) for p in self.base_tree if os.path.splitext(p)[1] in ('.py', '.ps1'))
|
||||||
|
|
||||||
|
del self.base_module_paths['__init__.py']
|
||||||
|
|
||||||
|
self.head_aliased_modules = set()
|
||||||
|
|
||||||
|
for path in self.head_tree:
|
||||||
|
filename = os.path.basename(path)
|
||||||
|
|
||||||
|
if filename.startswith('_') and filename != '__init__.py':
|
||||||
|
if os.path.islink(path):
|
||||||
|
self.head_aliased_modules.add(os.path.basename(os.path.realpath(path)))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _git(args):
|
||||||
|
cmd = ['git'] + args
|
||||||
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
return stdout.splitlines()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue