Skip to content

Commit

Permalink
Automatically install current collection
Browse files Browse the repository at this point in the history
If run inside a collection repository dependency step will first
build and install the current collection. This avoids failure to
run test scenarios unless user already installed the collection.

Fixes: #2997
  • Loading branch information
ssbarnea committed Dec 2, 2020
1 parent 29340d0 commit 97da33d
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 7 deletions.
25 changes: 25 additions & 0 deletions galaxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Molecule is not really a collection but this file is use for testing molecule
# ability to detect and install a local collection.
namespace: _test
name: molecule
version: 0.0.1
readme: README.rst
authors:
- Ansible
build_ignore:
- "**/*.egg-info"
- "**/.mypy_cache"
- .cache
- .coverage
- .eggs
- .github
- .gitignore
- .pytest_cache
- .vscode
- asset
- build
- coverage.xml
- dist
- docs/docstree/html
- pip-wheel-metadata
- tox.ini
3 changes: 2 additions & 1 deletion src/molecule/dependency/ansible_galaxy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def __init__(self, config):
self.invocations = [Roles(config), Collections(config)]

def execute(self):
super().execute()
for invoker in self.invocations:
invoker.execute()

Expand All @@ -85,7 +86,7 @@ def _has_requirements_file(self):
def default_env(self):
e = {}
for invoker in self.invocations:
e = util.merge(e, invoker.default_env)
e = util.merge_dicts(e, invoker.default_env)
return e

@property
Expand Down
30 changes: 28 additions & 2 deletions src/molecule/dependency/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@

import abc
import os
import re
import time
from pathlib import Path
from subprocess import CalledProcessError

from molecule import constants, util
from molecule.logger import get_logger
Expand Down Expand Up @@ -80,13 +83,36 @@ def execute_with_retries(self):
LOG.error(str(exception), self._sh_command)
util.sysexit(getattr(exception, "exit_code", constants.RC_UNKNOWN_ERROR))

@abc.abstractmethod
def execute(self): # pragma: no cover
def execute(self):
"""
Execute ``cmd`` and returns None.
:return: None
"""
collection_marker = os.path.join(util.find_vcs_root(), "galaxy.yml")
if os.path.isfile(collection_marker):
try:
LOG.info("Collection detected at %s", os.getcwd())

dist = Path(self._config.scenario.ephemeral_directory) / "dist"
dist.mkdir(parents=True, exist_ok=True)
result = util.run_command(
f"ansible-galaxy collection build -v -f --output-path {dist}",
env=self.default_env,
check=True,
echo=True,
)
archive = re.search(r"([^\s]+\.tar\.gz)$", result.stdout).groups()[0]
# no need to specify destination path because Molecule already defines
# custom isolated ANSIBLE_COLLECTIONS_PATH for each scenario
result = util.run_command(
f"ansible-galaxy collection install -f {archive}",
env=self.default_env,
check=True,
echo=True,
)
except CalledProcessError as e:
util.sysexit_with_message(e, e.returncode)

@abc.abstractproperty
def default_options(self): # pragma: no cover
Expand Down
1 change: 1 addition & 0 deletions src/molecule/dependency/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def bake(self) -> None:
self._sh_command = BakedCommand(cmd=self.command, env=self.env)

def execute(self):
super().execute()
if not self.enabled:
msg = "Skipping, dependency is disabled."
LOG.warning(msg)
Expand Down
15 changes: 11 additions & 4 deletions src/molecule/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import sys
from dataclasses import dataclass
from functools import lru_cache # noqa
from subprocess import CompletedProcess
from subprocess import CalledProcessError, CompletedProcess
from typing import Any, Dict, List, MutableMapping, NoReturn, Optional, Union

import jinja2
Expand Down Expand Up @@ -109,7 +109,7 @@ def sysexit_with_message(


def run_command(
cmd, env=None, debug=False, echo=False, quiet=False
cmd, env=None, debug=False, echo=False, quiet=False, check=False
) -> CompletedProcess:
"""
Execute the given command and returns None.
Expand All @@ -118,7 +118,6 @@ def run_command(
- a string or list of strings (similar to subprocess.run)
- a BakedCommand object (
:param debug: An optional bool to toggle debug output.
:return: ``sh`` object
"""
args = []
stdout = None
Expand All @@ -139,9 +138,17 @@ def run_command(
if debug:
print_environment_vars(env)

return run(
result = run(
args, env=env, stdout=stdout, stderr=stderr, echo=echo or debug, quiet=quiet
)
if result.returncode != 0 and check:
raise CalledProcessError(
returncode=result.returncode,
cmd=result.args,
output=result.stdout,
stderr=result.stderr,
)
return result


def os_walk(directory, pattern, excludes=[]):
Expand Down

0 comments on commit 97da33d

Please sign in to comment.