Support module alias and rename validation. (#22675)

Cache git ls-tree output to speed up validation.
pull/22677/head
Matt Clay 8 years ago committed by GitHub
parent dd8d699981
commit 1f337b6421

@ -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():
if path.endswith('/%s' % self.object_name):
return path
return None def _has_alias(self):
"""Return true if the module has any aliases."""
return self.object_name in self.git_cache.head_aliased_modules
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…
Cancel
Save