Skip to content

Commit

Permalink
Merge pull request #234 from grml/zeha/changelog-people
Browse files Browse the repository at this point in the history
build-driver: collect involved people in changes list
  • Loading branch information
zeha authored Dec 19, 2024
2 parents 92f86bd + 6f09c0f commit 1dee21f
Showing 1 changed file with 89 additions and 21 deletions.
110 changes: 89 additions & 21 deletions build-driver/generate-changes-list.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ def warn(self, message: str):
sys.stdout.write(f"W: {message}\n")


def run_x(args, check: bool = True, **kwargs):
# str-ify Paths, not necessary, but for readability in logs.
args = [arg if isinstance(arg, str) else str(arg) for arg in args]
args_str = '" "'.join(args)
print(f'D: Running "{args_str}"', flush=True)
return subprocess.run(args, check=check, **kwargs)


def parse_package_list(s: str) -> dict:
package_dict = {}
for line in s.split("\n"):
Expand All @@ -41,6 +49,23 @@ def parse_package_list(s: str) -> dict:
return package_dict


def sort_people(people: list[str]) -> list[str]:
"""Sort list of names, ignoring case"""
return sorted(people, key=lambda v: v.upper())


def unique_case_insensitive(strings: list[str]):
seen = set()
unique_strings = []
for string in strings:
upper = string.upper()
if upper in seen:
continue
seen.add(upper)
unique_strings.append(string)
return unique_strings


def build_changes(
output_filename: Path,
dpkg_list_new: Path,
Expand All @@ -53,6 +78,7 @@ def build_changes(
listener: Listener,
):
git_repo_workspace.mkdir(parents=True, exist_ok=True)
all_people = []

changelog = f"""------------------------------------------------------------------------
Generated by CI for job {job_name} {build_id}
Expand Down Expand Up @@ -90,39 +116,30 @@ def build_changes(
if old_version == version:
continue

# clone repo
git_url = f"{git_url_base}/{package}"
gitpath = git_repo_workspace / f"{package}.git"
if not gitpath.exists():
env = dict(os.environ) | {"GIT_TERMINAL_PROMPT": "0"}
subprocess.run(
["git", "clone", "--bare", "--single-branch", git_url, gitpath],
cwd=git_repo_workspace,
env=env,
)
if not gitpath.exists():
raise Exception("Repository not found")

# update repo
subprocess.run(["git", "remote", "set-url", "origin", git_url], cwd=gitpath)
subprocess.run(["git", "remote", "update", "--prune"], cwd=gitpath).check_returncode()
gitpath = fetch_grml_package_repo(git_repo_workspace, package, git_url)

if old_version:
range = f"v{old_version}..v{version}"
else:
range = f"v{version}"

result = subprocess.run(["git", "log", "--oneline", range], cwd=gitpath, capture_output=True)
if result.returncode != 0:
git_changes = "(failed)"
else:
git_changes = "\n ".join(result.stdout.decode().splitlines())
commits, people = get_grml_package_changes(gitpath, range)
all_people.extend(people)
commit_list = "\n ".join(commits)
people_list = "\n ".join(sort_people(people))
changelog += f"""Package {package}: {range} {'(new)' if not old_version else ''}
{git_changes}
{commit_list}
People:
{people_list}
------------------------------------------------------------------------
"""
except Exception as e:
listener.warn(f"Generating change report for package {package} failed: {e}")
changelog += f"""Package {package}: [failed]
------------------------------------------------------------------------
"""

else:
if old_version:
if old_version == version:
Expand All @@ -131,6 +148,14 @@ def build_changes(
else:
debian_changes["added"].append(package)


all_people = unique_case_insensitive(all_people)
all_people_list = "\n ".join(sort_people(all_people))
changelog += f"""All involved people:
{all_people_list}
------------------------------------------------------------------------
"""

changelog += """Changes to Debian package list:
Added:
{}
Expand Down Expand Up @@ -176,5 +201,48 @@ def main() -> int:
return 0


def fetch_grml_package_repo(git_repo_workspace: Path, package: str, git_url: str) -> Path:
"""Clone and update git repository."""
gitpath = git_repo_workspace / f"{package}.git"
if not gitpath.exists():
env = dict(os.environ) | {"GIT_TERMINAL_PROMPT": "0"}
run_x(
["git", "clone", "--bare", "--single-branch", git_url, gitpath],
cwd=git_repo_workspace,
env=env,
)
if not gitpath.exists():
raise Exception("Repository not found")

# update repo
run_x(["git", "remote", "set-url", "origin", git_url], cwd=gitpath)
run_x(["git", "remote", "update", "--prune"], cwd=gitpath).check_returncode()
return gitpath


def get_grml_package_changes(gitpath: Path, range: str) -> tuple[list[str], list[str]]:
trailers = ["Thanks", "Reported-By"]

git_format = "--format=tformat:Commit: %H %s%nAuthor: %aN%nCommitter: %cN%n"
for trailer in trailers:
git_format += f"%(trailers:key={trailer})%n"

git_log = run_x(["git", "log", git_format, range], cwd=gitpath, capture_output=True)

changes = []
people = []
for line in git_log.stdout.decode().splitlines():
line = line.strip()
if not line:
continue
key, value = line.split(': ', 1)
if key == 'Commit':
changes.append(value)
else:
people.append(value)

return changes, unique_case_insensitive(people)


if __name__ == "__main__":
sys.exit(main())

0 comments on commit 1dee21f

Please sign in to comment.