Skip to content

Commit 00e6106

Browse files
ziegenbergssbarnea
andauthored
Allow more control over verbosity when calling ansible-galaxy (#278)
* invoke ansible-galaxy with increased verbosity and always log stdout at INFO level This makes ansible-galaxy display important info, when logging level is increased. This helps debugging ansible-lint. Signed-off-by: Daniel Ziegenberg <[email protected]> * control verbosity from the consumer of compat library Signed-off-by: Daniel Ziegenberg <[email protected]> * fix tests Signed-off-by: Daniel Ziegenberg <[email protected]> --------- Signed-off-by: Daniel Ziegenberg <[email protected]> Co-authored-by: Sorin Sbarnea <[email protected]>
1 parent 2726e6b commit 00e6106

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

src/ansible_compat/runtime.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ def __init__(
165165
require_module: bool = False,
166166
max_retries: int = 0,
167167
environ: dict[str, str] | None = None,
168+
verbosity: int = 0,
168169
) -> None:
169170
"""Initialize Ansible runtime environment.
170171
@@ -186,12 +187,17 @@ def __init__(
186187
Default is 0, no retries.
187188
:param environ: Environment dictionary to use, if undefined
188189
``os.environ`` will be copied and used.
190+
:param verbosity: Verbosity level to use.
189191
"""
190192
self.project_dir = project_dir or Path.cwd()
191193
self.isolated = isolated
192194
self.max_retries = max_retries
193195
self.environ = environ or os.environ.copy()
194196
self.plugins = Plugins(runtime=self)
197+
self.verbosity = verbosity
198+
199+
self.initialize_logger(level=self.verbosity)
200+
195201
# Reduce noise from paramiko, unless user already defined PYTHONWARNINGS
196202
# paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated
197203
# https://github.com/paramiko/paramiko/issues/2038
@@ -235,6 +241,21 @@ def warning(
235241
# Monkey patch ansible warning in order to use warnings module.
236242
Display.warning = warning
237243

244+
def initialize_logger(self, level: int = 0) -> None:
245+
"""Set up the global logging level based on the verbosity number."""
246+
verbosity_map = {
247+
-2: logging.CRITICAL,
248+
-1: logging.ERROR,
249+
0: logging.WARNING,
250+
1: logging.INFO,
251+
2: logging.DEBUG,
252+
}
253+
# Unknown logging level is treated as DEBUG
254+
logging_level = verbosity_map.get(level, logging.DEBUG)
255+
_logger.setLevel(logging_level)
256+
# Use module-level _logger instance to validate it
257+
_logger.debug("Logging initialized to level %s", logging_level)
258+
238259
def _add_sys_path_to_collection_paths(self) -> None:
239260
"""Add the sys.path to the collection paths."""
240261
if self.config.collections_scan_sys_path:
@@ -505,9 +526,11 @@ def install_requirements( # noqa: C901
505526
"ansible-galaxy",
506527
"role",
507528
"install",
508-
"-vr",
529+
"-r",
509530
f"{requirement}",
510531
]
532+
if self.verbosity > 0:
533+
cmd.extend(["-" + ("v" * self.verbosity)])
511534
if self.cache_dir:
512535
cmd.extend(["--roles-path", f"{self.cache_dir}/roles"])
513536

@@ -519,8 +542,9 @@ def install_requirements( # noqa: C901
519542
_logger.info("Running %s", " ".join(cmd))
520543

521544
result = self.run(cmd, retry=retry)
545+
_logger.debug(result.stdout)
522546
if result.returncode != 0:
523-
_logger.error(result.stdout)
547+
_logger.error(result.stderr)
524548
raise AnsibleCommandError(result)
525549

526550
# Run galaxy collection install works on v2 requirements.yml
@@ -529,8 +553,10 @@ def install_requirements( # noqa: C901
529553
"ansible-galaxy",
530554
"collection",
531555
"install",
532-
"-v",
533556
]
557+
if self.verbosity > 0:
558+
cmd.extend(["-" + ("v" * self.verbosity)])
559+
534560
for collection in reqs_yaml["collections"]:
535561
if isinstance(collection, dict) and collection.get("type", "") == "git":
536562
_logger.info(
@@ -558,8 +584,8 @@ def install_requirements( # noqa: C901
558584
retry=retry,
559585
env={**os.environ, "ANSIBLE_COLLECTIONS_PATH": ":".join(cpaths)},
560586
)
587+
_logger.debug(result.stdout)
561588
if result.returncode != 0:
562-
_logger.error(result.stdout)
563589
_logger.error(result.stderr)
564590
raise AnsibleCommandError(result)
565591

test/test_runtime.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,11 @@ def cwd(path: Path) -> Iterator[None]:
240240
os.chdir(old_pwd)
241241

242242

243-
def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> None:
243+
def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture) -> None:
244244
"""Checks that the linter can auto-install requirements v1 when found."""
245+
runtime = Runtime(verbosity=1)
245246
path = Path(__file__).parent.parent / "examples" / "reqs_v1"
246-
with cwd(path), caplog.at_level(logging.INFO):
247+
with cwd(path):
247248
runtime.prepare_environment()
248249
assert any(
249250
msg.startswith("Running ansible-galaxy role install") for msg in caplog.messages
@@ -254,12 +255,12 @@ def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> N
254255
)
255256

256257

257-
def test_prerun_reqs_v2(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> None:
258+
def test_prerun_reqs_v2(caplog: pytest.LogCaptureFixture) -> None:
258259
"""Checks that the linter can auto-install requirements v2 when found."""
260+
runtime = Runtime(verbosity=1)
259261
path = (Path(__file__).parent.parent / "examples" / "reqs_v2").resolve()
260262
with cwd(path):
261-
with caplog.at_level(logging.INFO):
262-
runtime.prepare_environment()
263+
runtime.prepare_environment()
263264
assert any(
264265
msg.startswith("Running ansible-galaxy role install")
265266
for msg in caplog.messages
@@ -526,11 +527,10 @@ def test_install_galaxy_role(runtime_tmp: Runtime) -> None:
526527

527528

528529
def test_install_galaxy_role_unlink(
529-
runtime_tmp: Runtime,
530530
caplog: pytest.LogCaptureFixture,
531531
) -> None:
532532
"""Test ability to unlink incorrect symlinked roles."""
533-
caplog.set_level(logging.INFO)
533+
runtime_tmp = Runtime(verbosity=1)
534534
runtime_tmp.prepare_environment()
535535
pathlib.Path(f"{runtime_tmp.cache_dir}/roles").mkdir(parents=True, exist_ok=True)
536536
pathlib.Path(f"{runtime_tmp.cache_dir}/roles/acme.get_rich").symlink_to("/dev/null")

0 commit comments

Comments
 (0)