Skip to content

Commit

Permalink
Recognize standalone galaxy roles
Browse files Browse the repository at this point in the history
Identify when run with a standalone galaxy roles and attempt to make
them available.

This change may produce a specific error when 'author' field
inside galaxy_info is missing or not matching namespace requirements.

Fixes: #1329
  • Loading branch information
ssbarnea committed Feb 17, 2021
1 parent 1452a0f commit 9b8d31d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/ansiblelint/_prerun.py
@@ -1,4 +1,5 @@
import os
import pathlib
import re
import subprocess
import sys
Expand All @@ -13,7 +14,19 @@
ANSIBLE_MISSING_RC,
ANSIBLE_MOCKED_MODULE,
INVALID_CONFIG_RC,
INVALID_PREREQUISITES_RC,
)
from ansiblelint.loaders import yaml_from_file

MISSING_GALAXY_NAMESPACE = """\
A valid role namespace is required, edit meta/main.yml and assure that
author field is also a valid namespace:
galaxy_info:
author: your_galaxy_namespace
See: https://galaxy.ansible.com/docs/contributing/namespaces.html#galaxy-namespace-limitations
"""


def check_ansible_presence() -> None:
Expand Down Expand Up @@ -87,10 +100,33 @@ def prepare_environment() -> None:
if run.returncode != 0:
sys.exit(run.returncode)

_install_galaxy_role()
_perform_mockings()
_prepare_ansible_paths()


def _install_galaxy_role() -> None:
"""Detect standalone galaxy role and installs it."""
if not os.path.exists("meta/main.yml"):
return
yaml = yaml_from_file("meta/main.yml")
if 'galaxy_info' not in 'yaml':
return
role_name = yaml['galaxy_info'].get('role_name', None)
role_author = yaml['galaxy_info'].get('author', None)
if not role_name:
role_name = os.path.dirname(".")
role_name = re.sub(r'^{0}'.format(re.escape('ansible-role-')), '', role_name)
if not role_author or not re.match(r"[\w\d_]{2,}", role_name):
print(MISSING_GALAXY_NAMESPACE, file=sys.stderr)
sys.exit(INVALID_PREREQUISITES_RC)
p = pathlib.Path(".cache/roles")
p.mkdir(parents=True, exist_ok=True)
link_path = p / f"{role_author}.{role_name}"
if not link_path.exists:
link_path.symlink_to(pathlib.Path("../..", target_is_directory=True))


def _prepare_ansible_paths() -> None:
"""Configure Ansible environment variables."""
library_paths: List[str] = []
Expand Down
1 change: 1 addition & 0 deletions src/ansiblelint/constants.py
Expand Up @@ -15,6 +15,7 @@
INVALID_CONFIG_RC = 2
ANSIBLE_FAILURE_RC = 3
ANSIBLE_MISSING_RC = 4
INVALID_PREREQUISITES_RC = 10

# Minimal version of Ansible we support for runtime
ANSIBLE_MIN_VERSION = "2.9"
Expand Down
10 changes: 10 additions & 0 deletions src/ansiblelint/loaders.py
@@ -0,0 +1,10 @@
"""Utilities for loading various files."""
from typing import Any

import yaml


def yaml_from_file(filepath: str) -> Any:
"""Return a loaded YAML file."""
with open(filepath) as content:
return yaml.load(content, Loader=yaml.FullLoader)

0 comments on commit 9b8d31d

Please sign in to comment.