mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Additional reports (#18779)
* Additional reports * Fix default status to be a list
This commit is contained in:
parent
b5a63a556d
commit
ab43a26915
1 changed files with 70 additions and 15 deletions
|
@ -4,6 +4,7 @@ import ast
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from collections import defaultdict
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from pprint import pformat, pprint
|
from pprint import pformat, pprint
|
||||||
|
|
||||||
|
@ -17,6 +18,10 @@ from ansible.plugins import module_loader
|
||||||
NONMODULE_PY_FILES = frozenset(('async_wrapper.py',))
|
NONMODULE_PY_FILES = frozenset(('async_wrapper.py',))
|
||||||
NONMODULE_MODULE_NAMES = frozenset(os.path.splitext(p)[0] for p in NONMODULE_PY_FILES)
|
NONMODULE_MODULE_NAMES = frozenset(os.path.splitext(p)[0] for p in NONMODULE_PY_FILES)
|
||||||
|
|
||||||
|
# Default metadata
|
||||||
|
DEFAULT_METADATA = {'version': '1.0', 'status': ['preview'], 'supported_by':'community'}
|
||||||
|
|
||||||
|
|
||||||
class ParseError(Exception):
|
class ParseError(Exception):
|
||||||
"""Thrown when parsing a file fails"""
|
"""Thrown when parsing a file fails"""
|
||||||
pass
|
pass
|
||||||
|
@ -311,6 +316,7 @@ def parse_assigned_metadata_initial(csvfile):
|
||||||
else:
|
else:
|
||||||
print('Module %s has no supported_by field. Using community' % record[0])
|
print('Module %s has no supported_by field. Using community' % record[0])
|
||||||
supported_by = 'community'
|
supported_by = 'community'
|
||||||
|
supported_by = DEFAULT_METADATA['supported_by']
|
||||||
|
|
||||||
status = []
|
status = []
|
||||||
if record[6]:
|
if record[6]:
|
||||||
|
@ -318,9 +324,9 @@ def parse_assigned_metadata_initial(csvfile):
|
||||||
if record[7]:
|
if record[7]:
|
||||||
status.append('deprecated')
|
status.append('deprecated')
|
||||||
if not status:
|
if not status:
|
||||||
status.append('preview')
|
status.extend(DEFAULT_METADATA['status'])
|
||||||
|
|
||||||
yield (module, {'version': '1.0', 'supported_by': supported_by, 'status': status})
|
yield (module, {'version': DEFAULT_METADATA['version'], 'supported_by': supported_by, 'status': status})
|
||||||
|
|
||||||
|
|
||||||
def parse_assigned_metadata(csvfile):
|
def parse_assigned_metadata(csvfile):
|
||||||
|
@ -397,25 +403,41 @@ def write_metadata(filename, new_metadata, version=None, overwrite=False):
|
||||||
f.write(module_data)
|
f.write(module_data)
|
||||||
|
|
||||||
|
|
||||||
|
def return_metadata(plugins):
|
||||||
|
|
||||||
|
metadata = {}
|
||||||
|
for name, filename in plugins:
|
||||||
|
# There may be several files for a module (if it is written in another
|
||||||
|
# language, for instance) but only one of them (the .py file) should
|
||||||
|
# contain the metadata.
|
||||||
|
if name not in metadata or metadata[name] is not None:
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
module_data = f.read()
|
||||||
|
metadata[name] = extract_metadata(module_data)[0]
|
||||||
|
return metadata
|
||||||
|
|
||||||
def metadata_summary(plugins, version=None):
|
def metadata_summary(plugins, version=None):
|
||||||
"""Compile information about the metadata status for a list of modules
|
"""Compile information about the metadata status for a list of modules
|
||||||
|
|
||||||
:arg plugins: List of plugins to look for. Each entry in the list is
|
:arg plugins: List of plugins to look for. Each entry in the list is
|
||||||
a tuple of (module name, full path to module)
|
a tuple of (module name, full path to module)
|
||||||
:kwarg version: If given, make sure the modules have this version of
|
:kwarg version: If given, make sure the modules have this version of
|
||||||
metadata or highe.
|
metadata or higher.
|
||||||
:returns: A tuple consisting of a list of modules with no metadata at the
|
:returns: A tuple consisting of a list of modules with no metadata at the
|
||||||
required version and a list of files that have metadata at the
|
required version and a list of files that have metadata at the
|
||||||
required version.
|
required version.
|
||||||
"""
|
"""
|
||||||
no_metadata = {}
|
no_metadata = {}
|
||||||
has_metadata = {}
|
has_metadata = {}
|
||||||
for name, filename in plugins:
|
supported_by = defaultdict(set)
|
||||||
if name not in no_metadata and name not in has_metadata:
|
status = defaultdict(set)
|
||||||
with open(filename, 'rb') as f:
|
|
||||||
module_data = f.read()
|
|
||||||
|
|
||||||
metadata = extract_metadata(module_data)[0]
|
plugins = list(plugins)
|
||||||
|
all_mods_metadata = return_metadata(plugins)
|
||||||
|
for name, filename in plugins:
|
||||||
|
# Does the module have metadata?
|
||||||
|
if name not in no_metadata and name not in has_metadata:
|
||||||
|
metadata = all_mods_metadata[name]
|
||||||
if metadata is None:
|
if metadata is None:
|
||||||
no_metadata[name] = filename
|
no_metadata[name] = filename
|
||||||
elif version is not None and ('version' not in metadata or StrictVersion(metadata['version']) < StrictVersion(version)):
|
elif version is not None and ('version' not in metadata or StrictVersion(metadata['version']) < StrictVersion(version)):
|
||||||
|
@ -423,7 +445,17 @@ def metadata_summary(plugins, version=None):
|
||||||
else:
|
else:
|
||||||
has_metadata[name] = filename
|
has_metadata[name] = filename
|
||||||
|
|
||||||
return list(no_metadata.values()), list(has_metadata.values())
|
# What categories does the plugin belong in?
|
||||||
|
if all_mods_metadata[name] is None:
|
||||||
|
# No metadata for this module. Use the default metadata
|
||||||
|
supported_by[DEFAULT_METADATA['supported_by']].add(filename)
|
||||||
|
status[DEFAULT_METADATA['status'][0]].add(filename)
|
||||||
|
else:
|
||||||
|
supported_by[all_mods_metadata[name]['supported_by']].add(filename)
|
||||||
|
for one_status in all_mods_metadata[name]['status']:
|
||||||
|
status[one_status].add(filename)
|
||||||
|
|
||||||
|
return list(no_metadata.values()), list(has_metadata.values()), supported_by, status
|
||||||
|
|
||||||
#
|
#
|
||||||
# Subcommands
|
# Subcommands
|
||||||
|
@ -466,15 +498,12 @@ def add_default(version=None, overwrite=False):
|
||||||
plugins = ((os.path.splitext((os.path.basename(p)))[0], p) for p in plugins)
|
plugins = ((os.path.splitext((os.path.basename(p)))[0], p) for p in plugins)
|
||||||
plugins = (p for p in plugins if p[0] not in NONMODULE_MODULE_NAMES)
|
plugins = (p for p in plugins if p[0] not in NONMODULE_MODULE_NAMES)
|
||||||
|
|
||||||
# Default metadata
|
|
||||||
new_metadata = {'version': '1.0', 'status': 'preview', 'supported_by':'community'}
|
|
||||||
|
|
||||||
# Iterate through each plugin
|
# Iterate through each plugin
|
||||||
processed = set()
|
processed = set()
|
||||||
diagnostic_messages = []
|
diagnostic_messages = []
|
||||||
for name, filename in (info for info in plugins if info[0] not in processed):
|
for name, filename in (info for info in plugins if info[0] not in processed):
|
||||||
try:
|
try:
|
||||||
write_metadata(filename, new_metadata, version, overwrite)
|
write_metadata(filename, DEFAULT_METADATA, version, overwrite)
|
||||||
except ParseError as e:
|
except ParseError as e:
|
||||||
diagnostic_messages.append(e.args[0])
|
diagnostic_messages.append(e.args[0])
|
||||||
continue
|
continue
|
||||||
|
@ -496,17 +525,43 @@ def report(version=None):
|
||||||
"""
|
"""
|
||||||
# List of all plugins
|
# List of all plugins
|
||||||
plugins = module_loader.all(path_only=True)
|
plugins = module_loader.all(path_only=True)
|
||||||
|
plugins = list(plugins)
|
||||||
plugins = ((os.path.splitext((os.path.basename(p)))[0], p) for p in plugins)
|
plugins = ((os.path.splitext((os.path.basename(p)))[0], p) for p in plugins)
|
||||||
plugins = (p for p in plugins if p[0] != NONMODULE_MODULE_NAMES)
|
plugins = (p for p in plugins if p[0] != NONMODULE_MODULE_NAMES)
|
||||||
|
plugins = list(plugins)
|
||||||
|
|
||||||
no_metadata, has_metadata = metadata_summary(plugins, version=version)
|
no_metadata, has_metadata, support, status = metadata_summary(plugins, version=version)
|
||||||
|
|
||||||
print('== Has metadata ==')
|
print('== Has metadata ==')
|
||||||
pprint(sorted(has_metadata))
|
pprint(sorted(has_metadata))
|
||||||
|
print('')
|
||||||
|
|
||||||
print('== Has no metadata ==')
|
print('== Has no metadata ==')
|
||||||
pprint(sorted(no_metadata))
|
pprint(sorted(no_metadata))
|
||||||
print('')
|
print('')
|
||||||
print('No Metadata: {0} Has Metadata: {1}'.format(len(no_metadata), len(has_metadata)))
|
|
||||||
|
print('== Supported by core ==')
|
||||||
|
pprint(sorted(support['core']))
|
||||||
|
print('== Supported by committers ==')
|
||||||
|
pprint(sorted(support['committer']))
|
||||||
|
print('== Supported by community ==')
|
||||||
|
pprint(sorted(support['community']))
|
||||||
|
print('')
|
||||||
|
|
||||||
|
print('== Status: stableinterface ==')
|
||||||
|
pprint(sorted(status['stableinterface']))
|
||||||
|
print('== Status: preview ==')
|
||||||
|
pprint(sorted(status['preview']))
|
||||||
|
print('== Status: deprecated ==')
|
||||||
|
pprint(sorted(status['deprecated']))
|
||||||
|
print('== Status: removed ==')
|
||||||
|
pprint(sorted(status['removed']))
|
||||||
|
print('')
|
||||||
|
|
||||||
|
print('== Summary ==')
|
||||||
|
print('No Metadata: {0} Has Metadata: {1}'.format(len(no_metadata), len(has_metadata)))
|
||||||
|
print('Supported by core: {0} Supported by community: {1} Supported by committer: {2}'.format(len(support['core']), len(support['community']), len(support['committer'])))
|
||||||
|
print('Status StableInterface: {0} Status Preview: {1} Status Deprecated: {2} Status Removed: {3}'.format(len(status['stableinterface']), len(status['preview']), len(status['deprecated']), len(status['removed'])))
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue