Repository URL to install this package:
|
Version:
1.0.0 ▾
|
# -*- coding: utf-8 -*-
# python 3 compatibility
from __future__ import absolute_import, division, print_function, unicode_literals
import fnmatch
import logging
import os
from six import string_types
from frutils import dict_merge
from frutils.defaults import DEFAULT_EXCLUDE_DIRS
log = logging.getLogger("nsbl")
ROLE_CACHE = {}
ROLE_MARKER_FOLDERNAME = "meta"
ROLE_META_FILENAME = "main.yml"
def calculate_role_repos(role_repos):
"""Utility method to calculate which role repos to use.
Role repos are folders containing ansible roles, and an (optional) task
description file which is used to translate task-names in a task config
file into roles or ansible tasks.
Args:
role_repos (list): a string or list of strings of local folders containing ansible roles
Returns:
list: a list of all local role repos to be used
"""
if not role_repos:
role_repos = []
if isinstance(role_repos, string_types):
role_repos = [role_repos]
role_repos[:] = [os.path.realpath(os.path.expanduser(rr)) for rr in role_repos]
role_repos[:] = [
rr
for rr in role_repos
if os.path.exists(rr) and os.path.isdir(os.path.realpath(rr))
]
log.debug("final role_repos: {}".format(role_repos))
return role_repos
def find_roles_in_repos(role_repos):
if isinstance(role_repos, string_types):
role_repos = [role_repos]
all_role_paths = set()
result = {}
for rr in role_repos:
roles = find_roles_in_repo(rr)
for v in roles.values():
all_role_paths.add(v)
# we want roles found first to take precedence
result = dict_merge(roles, result, copy_dct=True)
return result, all_role_paths
def find_roles_in_repo(role_repo):
"""Utility function to find all roles in a role_repo.
Args:
role_repo: the path to the role repo
Returns:
dict: a dictionary with the name of the role as key, and the path to the role as value
"""
if role_repo in ROLE_CACHE.keys():
return ROLE_CACHE[role_repo]
result = {}
try:
for root, dirnames, filenames in os.walk(
os.path.realpath(role_repo), topdown=True, followlinks=True
):
dirnames[:] = [d for d in dirnames if d not in DEFAULT_EXCLUDE_DIRS]
# check for meta folders
for dirname in fnmatch.filter(dirnames, ROLE_MARKER_FOLDERNAME):
meta_file = os.path.realpath(
os.path.join(root, dirname, ROLE_META_FILENAME)
)
if not os.path.exists(meta_file):
continue
role_folder = root
role_name = os.path.basename(role_folder)
result[role_name] = role_folder
except (UnicodeDecodeError):
print(
" X one or more filenames under '{}' can't be decoded, ignoring. This can cause problems later. ".format(
root
)
)
ROLE_CACHE[role_repo] = result
return result