diff --git a/README.md b/README.md index 0222bf5..d4c1bdc 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,15 @@ Every `markdawn` file under the `tests` directory that already contains mark hea ``` -The directive is only valid for the specified directory, in the example above files places under `tests/integration/` will not have the headers appended. +The directive supports glob matching and prioritize the longest directory first, for example: + +```yaml +default_headers: | + tests/**=FOO->Tests + tests/resources/**=FOO->Tests->Resources +``` + +Files under `tests/resources/` will have `FOO->Tests->Resources` as headers, while files under `tests/other-dir` will have `FOO->Tests`. ## Example workflow diff --git a/mark2confluence/main.py b/mark2confluence/main.py index 530af26..bfc05e8 100755 --- a/mark2confluence/main.py +++ b/mark2confluence/main.py @@ -4,6 +4,7 @@ import re import subprocess from datetime import datetime,timedelta +from fnmatch import fnmatch from typing import List, Tuple import jinja2 from loguru import logger @@ -194,6 +195,13 @@ def get_header(self) -> str: header += f"\n" return header + def is_directory_included(self, directory: str) -> bool: + global cfg + sanitized_dir = directory.replace(f"{cfg.github.WORKSPACE}/", "") + if not sanitized_dir.endswith("/"): + sanitized_dir += "/" + return fnmatch(sanitized_dir, self.directory) + def _parse_parent_string(parent_string: str) -> Tuple[str, str, List[str]]: dir_separator = "=" spaces_separator = "->" @@ -223,20 +231,21 @@ def get_default_parents(parents_string: str) -> List[ParentCfg]: for parent_string in parents_string.split("\n"): directory, space, parents = _parse_parent_string(parent_string) default_parents.append(ParentCfg(directory, space, parents)) + default_parents.sort(key=lambda cfg: len(cfg.directory), reverse=True) return default_parents def inject_default_parents(path: str, default_parents_cfg: List[ParentCfg]): global cfg - file_dir = f"{os.path.dirname(os.path.relpath(path))}/" + file_dir = f"{os.path.dirname(os.path.abspath(path))}" for parent_cfg in default_parents_cfg: - cfg_abs_dir = f"{cfg.github.WORKSPACE}/{parent_cfg.directory}" - if os.path.isdir(cfg_abs_dir) and os.path.samefile(file_dir, cfg_abs_dir): + if parent_cfg.is_directory_included(file_dir): header = parent_cfg.get_header() with open(path, 'r') as f: file_content = f.read() file_content = f"{header}{file_content}" with open(path, "w") as f: f.write(file_content) + return def main()->int: diff --git a/tests/test_main.py b/tests/test_main.py index 9bd389c..d656e0a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,10 +1,12 @@ import os import pytest import shutil +from supermutes import dot import mark2confluence.main as main RESOURCE_DIR = f"{os.path.dirname(os.path.abspath(__file__))}/resources" +WORKSPACE = os.path.realpath(f"{os.path.dirname(os.path.abspath(__file__))}/..") def clean_github_environment_variables(): if(os.getenv("CI", False)): @@ -121,17 +123,24 @@ def test_get_default_parents(string, expected_parents_count): def test_ParentCfg_get_header(cfg: main.ParentCfg, expected_header): assert cfg.get_header() == expected_header -def test_inject_default_parents(): +def test_inject_default_parents(monkeypatch): + monkeypatch.setattr('mark2confluence.main.cfg', dot.dotify({"github": {"WORKSPACE": WORKSPACE}})) + base_dir = f"{RESOURCE_DIR}/markdown/test_inject_default_parents" source_file_path = f"{base_dir}/0-input.md" expected_file_path = f"{base_dir}/0-output.md" - parsed_file_path = "tests/parsed_file.md" + parsed_file_dir = f"{WORKSPACE}/tests/foo" + parsed_file_path = f"{parsed_file_dir}/parsed_file.md" cfgs = [ - main.ParentCfg(directory="tests/", space="FOO", parents=["BAR"]), + main.ParentCfg(directory="tests/foo/bar", space="FOO", parents=["BAZ"]), + main.ParentCfg(directory="tests/foo/*", space="FOO", parents=["BAR"]), + main.ParentCfg(directory="tests/*", space="FOO", parents=["BAZ"]), main.ParentCfg(directory="mark2confluence/", space="BOZ", parents=["BIZ"]), ] + os.makedirs(parsed_file_dir, exist_ok=True) shutil.copy(source_file_path, parsed_file_path) + main.inject_default_parents(parsed_file_path, cfgs) with open(parsed_file_path, "r") as f: @@ -142,4 +151,4 @@ def test_inject_default_parents(): try: assert parsed_file_content == expected_file_content finally: - os.remove(parsed_file_path) + shutil.rmtree(parsed_file_dir)