|
5 | 5 | import json
|
6 | 6 | import glob
|
7 | 7 | import pathlib
|
| 8 | +import subprocess |
8 | 9 | import typing
|
9 | 10 |
|
10 | 11 | # Before adding a new entry to this list, double check that
|
@@ -78,6 +79,33 @@ def spdx_id(value: str) -> str:
|
78 | 79 | return re.sub(r"[^a-zA-Z0-9.\-]+", "-", value)
|
79 | 80 |
|
80 | 81 |
|
| 82 | +def filter_gitignored_paths(paths: list[str]) -> list[str]: |
| 83 | + """ |
| 84 | + Filter out paths excluded by the gitignore file. |
| 85 | + The output of 'git check-ignore --non-matching --verbose' looks |
| 86 | + like this for non-matching (included) files: |
| 87 | +
|
| 88 | + '::<whitespace><path>' |
| 89 | +
|
| 90 | + And looks like this for matching (excluded) files: |
| 91 | +
|
| 92 | + '.gitignore:9:*.a Tools/lib.a' |
| 93 | + """ |
| 94 | + # Filter out files in gitignore. |
| 95 | + # Non-matching files show up as '::<whitespace><path>' |
| 96 | + git_check_ignore_proc = subprocess.run( |
| 97 | + ["git", "check-ignore", "--verbose", "--non-matching", *paths], |
| 98 | + check=False, |
| 99 | + stdout=subprocess.PIPE |
| 100 | + ) |
| 101 | + # 1 means matches, 0 means no matches. |
| 102 | + assert git_check_ignore_proc.returncode in (0, 1) |
| 103 | + |
| 104 | + # Return the list of paths sorted |
| 105 | + git_check_ignore_lines = git_check_ignore_proc.stdout.decode().splitlines() |
| 106 | + return sorted([line.split()[-1] for line in git_check_ignore_lines if line.startswith("::")]) |
| 107 | + |
| 108 | + |
81 | 109 | def main() -> None:
|
82 | 110 | root_dir = pathlib.Path(__file__).parent.parent.parent
|
83 | 111 | sbom_path = root_dir / "Misc/sbom.spdx.json"
|
@@ -108,7 +136,10 @@ def main() -> None:
|
108 | 136 | package_spdx_id = spdx_id(f"SPDXRef-PACKAGE-{name}")
|
109 | 137 | exclude = files.exclude or ()
|
110 | 138 | for include in sorted(files.include):
|
111 |
| - paths = sorted(glob.glob(include, root_dir=root_dir, recursive=True)) |
| 139 | + |
| 140 | + # Find all the paths and then filter them through .gitignore. |
| 141 | + paths = glob.glob(include, root_dir=root_dir, recursive=True) |
| 142 | + paths = filter_gitignored_paths(paths) |
112 | 143 | assert paths, include # Make sure that every value returns something!
|
113 | 144 |
|
114 | 145 | for path in paths:
|
|
0 commit comments