Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions ansigenome/data/README.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
{% if ansigenome_info.travis|d() %}
[![Travis CI](http://img.shields.io/travis/{{ scm.user + '/' + role.slug }}.svg?style=flat)](http://travis-ci.org/{{ scm.user + '/' + role.slug }})
{% endif %}
{% if ansigenome_info.galaxy_id|d() %}
[![Ansible Galaxy](http://img.shields.io/badge/galaxy-{{ role.galaxy_name | replace('-', '--')}}-660198.svg?style=flat)](https://galaxy.ansible.com/detail#/role/{{ ansigenome_info.galaxy_id }})
{% if ansigenome_info.galaxy_url|d() %}
[![Ansible Galaxy](http://img.shields.io/badge/galaxy-{{ role.galaxy_name | replace('-', '--')}}-660198.svg?style=flat)]({{ ansigenome_info.galaxy_url }})
{% endif %}
{% if galaxy_info.platforms|d() %}
[![Platforms](http://img.shields.io/badge/platforms-{{ galaxy_info.platforms | map(attribute='name') | sort | join('%20/%20') | lower }}-lightgrey.svg?style=flat)](#)
Expand Down Expand Up @@ -53,7 +53,7 @@ in a production environment.
{% endblock %}
{% endif %}

{% if ansigenome_info.galaxy_id|d() %}
{% if ansigenome_info.galaxy_url|d() %}
{% block installation %}
### Installation

Expand Down Expand Up @@ -110,10 +110,8 @@ List of internal variables used by the role:
{% block authors %}
### Authors and license

`{{ role.name }}` role was written by:

{% for credit in authors %}
- {{ "[" if credit.url|d() else "" }}{{ credit.name }}{{ "](" + credit.url + ")" if credit.url|d() else "" }}{% if credit.email|d() %} | [e-mail](mailto:{{ credit.email }}){% endif %}{% if credit.twitter|d() %} | [Twitter](https://twitter.com/{{ credit.twitter }}){% endif %}{% if credit.github|d() %} | [GitHub](https://github.com/{{ credit.github }}){% endif %}
- {{ "[" if credit.url|d() else "" }}{{ credit.name }}{{ "](" + credit.url + ")" if credit.url|d() else "" }}{{ " (maintainer)" if (credit.maintainer|d()) else "" }}{% if credit.email|d() %} | [e-mail](mailto:{{ credit.email }}){% endif %}{% if credit.twitter|d() %} | [Twitter](https://twitter.com/{{ credit.twitter }}){% endif %}{% if credit.github|d() %} | [GitHub](https://github.com/{{ credit.github }}){% endif %}

{% endfor %}

Expand Down
88 changes: 84 additions & 4 deletions ansigenome/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,56 @@ def __init__(self, args, options, config,
if self.export:
self.export_roles()

def _get_maintainers_from_line(self, line):
# Modeled with the natural language processing from AIML in mind.
# TODO: Remove redundancy. Duplicated into ansigenome source code. Origin: debops-api
_re = re.match(
r'^[^.]*?maintainers?[\W_]+(:?is|are)[\W_]+`?(?P<nicks>.+?)\.?$',
line,
re.IGNORECASE
)
if _re:
return [x.rstrip('_') for x in re.split(r'[\s,]+', _re.group('nicks')) if x not in ['and', ',']]
else:
return None

def _get_maintainers_from_changelog(self, changes_file):
# TODO: Remove redundancy. Duplicated into ansigenome source code. Origin: debops-api
"""
Extract the maintainer from CHANGES.rst file and return the nickname of
the maintainer.
"""

try:
with open(changes_file, 'r') as changes_fh:
for line in changes_fh:
nick = self._get_maintainers_from_line(line)
if nick is not None:
return nick
except:
return None
return None

def _get_debops_keyring_entities(self, keyids_file):
"""
Return list of nicks defined in the https://github.com/debops/debops-keyring/blob/master/keyids
file.
The file is assumed to be locally available to avoid to contact external servers.
"""

entities = set()

if keyids_file:
with open(keyids_file, 'r') as keyids_fd:
for keyid_line in keyids_fd:
_re = re.search(
r'^(?P<keyid>[^ ]+) (?P<name>[^<]+) <(?P<nick>.*)>$',
keyid_line,
)
entities.add(_re.group('nick'))

return entities

def limit_roles(self):
"""
Limit the roles being scanned.
Expand All @@ -108,6 +158,15 @@ def scan_roles(self):
self.paths["role"] = os.path.join(self.roles_path, key)
self.paths["meta"] = os.path.join(self.paths["role"], "meta",
"main.yml")
self.paths["ansigenome"] = os.path.join(
self.paths["role"],
"meta",
"ansigenome.yml"
)
self.paths["changelog"] = os.path.join(
self.paths["role"],
"CHANGES.rst"
)
self.paths["readme"] = os.path.join(self.paths["role"],
"README.{0}"
.format(self.readme_format))
Expand All @@ -119,14 +178,14 @@ def scan_roles(self):
# we are writing a readme file which means the state of the role
# needs to be updated before it gets output by the ui
if self.gendoc:
if self.valid_meta(key):
if self.read_and_validate_meta(key):
self.make_meta_dict_consistent()
self.set_readme_template_vars(key, value)
self.write_readme(key)
# only load the meta file when generating meta files
elif self.genmeta:
self.make_or_augment_meta(key)
if self.valid_meta(key):
if self.read_and_validate_meta(key):
self.make_meta_dict_consistent()
self.write_meta(key)
else:
Expand Down Expand Up @@ -336,12 +395,33 @@ def tally_role_columns(self):
totals["files"] = sum(roles[item]["total_files"] for item in roles)
totals["lines"] = sum(roles[item]["total_lines"] for item in roles)

def valid_meta(self, role):
def read_and_validate_meta(self, role):
"""
Return whether or not the meta file being read is valid.
Read the meta files and return whether or not the meta file being read
is valid.
"""
if os.path.exists(self.paths["meta"]):
self.meta_dict = utils.yaml_load(self.paths["meta"])
if os.path.exists(self.paths["ansigenome"]):
self.meta_dict['ansigenome_info'] = utils.yaml_load(self.paths["ansigenome"])['ansigenome_info']
maintainers = self._get_maintainers_from_changelog(self.paths["changelog"])
keyring_entities = self._get_debops_keyring_entities(self.config.get('keyids_file'))
if 'ansigenome_info' in self.meta_dict:
if maintainers:
authors = []
for ind, author in enumerate(self.meta_dict['ansigenome_info']['authors']):
author = self.meta_dict['ansigenome_info']['authors'][ind]
author['maintainer'] = author['github'] in maintainers
if author['github'] in keyring_entities and 'url' not in author:
author['url'] = 'https://docs.debops.org/en/latest/debops-keyring/docs/entities.html#debops-keyring-entity-{nick}'.format(
nick=author['github'],
)
authors.append(author)
authors_sorted = []
authors_sorted.append(authors.pop(0))
authors_sorted += sorted(authors, key=lambda k: k['maintainer'], reverse=True)
self.meta_dict['ansigenome_info']['authors'] = authors_sorted

else:
self.report["state"]["missing_meta_role"] += 1
self.report["roles"][role]["state"] = "missing_meta"
Expand Down
4 changes: 2 additions & 2 deletions ansigenome/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ def yaml_load(path, input="", err_quit=False):
"""
try:
if len(input) > 0:
return yaml.load(input)
return yaml.safe_load(input)
elif len(path) > 0:
return yaml.load(file_to_string(path))
return yaml.safe_load(file_to_string(path))
except Exception as err:
file = os.path.basename(path)
ui.error("",
Expand Down