diff --git a/.gitignore b/.gitignore index 59a247c..111c9b0 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,4 @@ ansible_collections # Generated by setuptools-scm src/ansible_compat/_version.py node_modules +_readthedocs diff --git a/mkdocs.yml b/mkdocs.yml index 2c54b28..32dbd11 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -91,4 +91,4 @@ markdown_extensions: custom_fences: - name: mermaid class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format + format: "" diff --git a/readthedocs.yml b/readthedocs.yml index a367ff5..fe68595 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -6,14 +6,19 @@ submodules: mkdocs: fail_on_warning: true + configuration: mkdocs.yml build: os: ubuntu-24.04 tools: python: "3.11" - + commands: + - pip install --user tox + - python3 -m tox -e docs python: install: + - method: pip + path: tox - method: pip path: . extra_requirements: diff --git a/src/ansible_compat/runtime.py b/src/ansible_compat/runtime.py index 030497c..ca35e02 100644 --- a/src/ansible_compat/runtime.py +++ b/src/ansible_compat/runtime.py @@ -52,8 +52,8 @@ _logger = logging.getLogger(__name__) # regex to extract the first version from a collection range specifier -version_re = re.compile(":[>=<]*([^,]*)") -namespace_re = re.compile("^[a-z][a-z0-9_]+$") +version_re = re.compile(r":[>=<]*([^,]*)") +namespace_re = re.compile(r"^[a-z][a-z0-9_]+$") class AnsibleWarning(Warning): @@ -660,11 +660,10 @@ def prepare_environment( # noqa: C901 if not install_local: return - for gpath in search_galaxy_paths(self.project_dir): + for item in search_galaxy_paths(self.project_dir): # processing all found galaxy.yml files - galaxy_path = Path(gpath) - if galaxy_path.exists(): - data = yaml_from_file(galaxy_path) + if item.exists(): + data = yaml_from_file(item) if isinstance(data, dict) and "dependencies" in data: for name, required_version in data["dependencies"].items(): _logger.info( @@ -685,7 +684,8 @@ def prepare_environment( # noqa: C901 destination=destination, ) - if (self.project_dir / "galaxy.yml").exists(): + galaxy_path = self.project_dir / "galaxy.yml" + if (galaxy_path).exists(): if destination: # while function can return None, that would not break the logic colpath = Path( @@ -979,20 +979,27 @@ def _get_galaxy_role_name(galaxy_infos: dict[str, Any]) -> str: return result -def search_galaxy_paths(search_dir: Path) -> list[str]: - """Search for galaxy paths (only one level deep).""" - galaxy_paths: list[str] = [] - for file in [".", *os.listdir(search_dir)]: +def search_galaxy_paths(search_dir: Path) -> list[Path]: + """Search for galaxy paths (only one level deep). + + Returns: + list[Path]: List of galaxy.yml found. + """ + galaxy_paths: list[Path] = [] + for item in [Path(), *search_dir.iterdir()]: # We ignore any folders that are not valid namespaces, just like # ansible galaxy does at this moment. - if file != "." and not namespace_re.match(file): + file_path = item.resolve() + if file_path.is_file() and file_path.name == "galaxy.yml": + galaxy_paths.append(file_path) continue - file_path = search_dir / file / "galaxy.yml" - if file_path.is_file(): - galaxy_paths.append(str(file_path)) + if file_path.is_dir() and namespace_re.match(file_path.name): + file_path /= "galaxy.yml" + if file_path.exists(): + galaxy_paths.append(file_path) return galaxy_paths def is_url(name: str) -> bool: """Return True if a dependency name looks like an URL.""" - return bool(re.match("^git[+@]", name)) + return bool(re.match(r"^git[+@]", name)) diff --git a/test/test_runtime.py b/test/test_runtime.py index edb5c6b..b665f3e 100644 --- a/test/test_runtime.py +++ b/test/test_runtime.py @@ -937,25 +937,25 @@ def test_runtime_plugins(runtime: Runtime) -> None: ("path", "result"), ( pytest.param( - "test/assets/galaxy_paths", - ["test/assets/galaxy_paths/foo/galaxy.yml"], + Path("test/assets/galaxy_paths"), + [Path("test/assets/galaxy_paths/foo/galaxy.yml").resolve()], id="1", ), pytest.param( - "test/collections", + Path("test/collections"), [], # should find nothing because these folders are not valid namespaces id="2", ), pytest.param( - "test/assets/galaxy_paths/foo", - ["test/assets/galaxy_paths/foo/galaxy.yml"], + Path("test/assets/galaxy_paths/foo"), + [Path("test/assets/galaxy_paths/foo/galaxy.yml").resolve()], id="3", ), ), ) -def test_galaxy_path(path: str, result: list[str]) -> None: +def test_galaxy_path(path: Path, result: list[Path]) -> None: """Check behavior of galaxy path search.""" - assert search_galaxy_paths(Path(path)) == result + assert search_galaxy_paths(path) == result @pytest.mark.parametrize( diff --git a/tox.ini b/tox.ini index 2ef8a8b..e4de270 100644 --- a/tox.ini +++ b/tox.ini @@ -170,7 +170,10 @@ commands = [testenv:docs] description = Build docs commands = - mkdocs {posargs:build} --strict + mkdocs {posargs:build --strict --site-dir=_readthedocs/html/} +setenv = + # https://squidfunk.github.io/mkdocs-material/plugins/requirements/image-processing/#troubleshooting + DYLD_FALLBACK_LIBRARY_PATH = /opt/homebrew/lib:{env:LD_LIBRARY_PATH} extras = docs passenv = *