Helper function to map input files/directories to output files/directories. mappings: list of dicts with 'src' (glob pattern) and 'dst' (relative to target_base or absolute) 'src' can be a single file or a directory (if it ends with /).
(mappings, target_base)
| 8 | from textwrap import dedent |
| 9 | |
| 10 | def map_copy(mappings, target_base): |
| 11 | """ |
| 12 | Helper function to map input files/directories to output files/directories. |
| 13 | mappings: list of dicts with 'src' (glob pattern) and 'dst' (relative to target_base or absolute) |
| 14 | 'src' can be a single file or a directory (if it ends with /). |
| 15 | """ |
| 16 | for mapping in mappings: |
| 17 | src_pattern = mapping['src'] |
| 18 | dst_rel = mapping['dst'] |
| 19 | dst_path = os.path.join(target_base, dst_rel) |
| 20 | |
| 21 | # To preserve directory structure, we need to know where the wildcard starts |
| 22 | # or have a way to determine the "base" of the search. |
| 23 | # We'll split the pattern into a fixed base and a pattern part. |
| 24 | |
| 25 | # Simple heuristic: find the first occurrence of '*' or '?' |
| 26 | wildcard_idx = -1 |
| 27 | for i, char in enumerate(src_pattern): |
| 28 | if char in '*?': |
| 29 | wildcard_idx = i |
| 30 | break |
| 31 | |
| 32 | if wildcard_idx != -1: |
| 33 | # Found a wildcard. The base is the directory containing it. |
| 34 | pattern_base = os.path.dirname(src_pattern[:wildcard_idx]) |
| 35 | else: |
| 36 | # No wildcard. If it's a directory, we might want to preserve its name? |
| 37 | # For now, let's treat no-wildcard as no relative structure needed. |
| 38 | pattern_base = None |
| 39 | |
| 40 | src_files = glob.glob(src_pattern, recursive=True) |
| 41 | if not src_files: |
| 42 | continue |
| 43 | |
| 44 | for src in src_files: |
| 45 | if os.path.isdir(src): |
| 46 | continue |
| 47 | |
| 48 | if pattern_base and src.startswith(pattern_base): |
| 49 | # Calculate relative path from the base of the glob pattern |
| 50 | rel_src = os.path.relpath(src, pattern_base) |
| 51 | # If dst_rel ends with /, it's a target directory |
| 52 | if dst_rel.endswith('/') or os.path.isdir(dst_path): |
| 53 | final_dst = os.path.join(dst_path, rel_src) |
| 54 | else: |
| 55 | # If dst_rel is a file, we can't really preserve structure |
| 56 | # unless we join it. But usually it's a dir if structure is preserved. |
| 57 | final_dst = dst_path |
| 58 | else: |
| 59 | final_dst = dst_path if not (dst_rel.endswith('/') or os.path.isdir(dst_path)) else os.path.join(dst_path, os.path.basename(src)) |
| 60 | |
| 61 | os.makedirs(os.path.dirname(final_dst), exist_ok=True) |
| 62 | shutil.copy2(src, final_dst) |
| 63 | |
| 64 | def get_driver_mappings(driver_name): |
| 65 | return [ |
no test coverage detected