Skip to content

Commit b683ee6

Browse files
committed
[ULS] Pull reusable spec/tag helpers into ciq_helpers
1 parent 936e093 commit b683ee6

File tree

2 files changed

+95
-75
lines changed

2 files changed

+95
-75
lines changed

ciq_helpers.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,61 @@ def last_git_tag(repo):
344344
if not r:
345345
raise Exception("Could not find last tag for", repo)
346346
return r
347+
348+
349+
def get_git_user(repo):
350+
"""Get the git user name and email from a repo's config.
351+
352+
Returns a (name, email) tuple.
353+
Raises git.exc.GitCommandError if user.name or user.email are not configured.
354+
"""
355+
name = repo.git.config("user.name")
356+
email = repo.git.config("user.email")
357+
return name, email
358+
359+
360+
def parse_kernel_tag(tag):
361+
"""Validate and parse a kernel version tag like 'v6.12.74' or '6.12.74'.
362+
363+
Returns the version string without the 'v' prefix (e.g., '6.12.74').
364+
Raises ValueError if the tag format is invalid.
365+
"""
366+
tag_without_v = tag.lstrip("v")
367+
tag_parts = tag_without_v.split(".")
368+
if len(tag_parts) != 3:
369+
raise ValueError(f"Invalid kernel tag format: {tag} (expected vX.Y.Z or X.Y.Z, e.g., v6.12.74)")
370+
try:
371+
for part in tag_parts:
372+
int(part)
373+
except ValueError:
374+
raise ValueError(f"Invalid kernel tag format: {tag} (version parts must be numeric)")
375+
return tag_without_v
376+
377+
378+
def replace_spec_changelog(spec_lines, new_changelog_lines):
379+
"""Replace the %changelog section in spec_lines with new_changelog_lines.
380+
381+
Preserves any trailing comment lines (starting with #) from the original changelog.
382+
Returns a new list of lines.
383+
"""
384+
# Collect trailing comments from the original changelog section
385+
trailing_comments = []
386+
in_changelog = False
387+
for line in spec_lines:
388+
if line.startswith("%changelog"):
389+
in_changelog = True
390+
continue
391+
if in_changelog and (line.startswith("#") or line.startswith("###")):
392+
trailing_comments.append(line)
393+
394+
# Build new spec, replacing everything from %changelog onward
395+
new_spec = []
396+
for line in spec_lines:
397+
if line.startswith("%changelog"):
398+
new_spec.append(line)
399+
new_spec.extend(new_changelog_lines)
400+
new_spec.extend(trailing_comments)
401+
break
402+
new_spec.append(line)
403+
404+
return new_spec

update_lt_spec.py

Lines changed: 37 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,26 @@
1717
print("ERROR: GitPython is not installed. Install it with: pip install GitPython")
1818
sys.exit(1)
1919

20-
from ciq_helpers import last_git_tag
20+
from ciq_helpers import get_git_user, last_git_tag, parse_kernel_tag, replace_spec_changelog
2121

2222

23-
def calculate_lt_rebase_versions(upstream_tag, distlocalversion, dist):
23+
def calculate_lt_rebase_versions(kernel_version, distlocalversion, dist):
2424
"""Calculate version strings for LT rebase.
2525
2626
Arguments:
27-
upstream_tag: Git tag from git describe (e.g., 'v6.12.74')
27+
kernel_version: Kernel version string (e.g., '6.12.74')
2828
distlocalversion: DISTLOCALVERSION string (e.g., '.1.0.0')
2929
dist: DIST string (e.g., '.el9_clk')
3030
3131
Returns:
3232
Tuple of (full_kernel_version, tag_version, spectarfile_release, new_tag, major_version)
3333
"""
34-
# Remove 'v' prefix if present
35-
full_kernel_version = upstream_tag.lstrip("v")
36-
tag_version = f"{full_kernel_version}-1"
34+
tag_version = f"{kernel_version}-1"
3735
spectarfile_release = f"{tag_version}{distlocalversion}{dist}"
3836
new_tag = f"ciq_kernel-{tag_version}"
39-
major_version = full_kernel_version.split(".")[0]
37+
major_version = kernel_version.split(".")[0]
4038

41-
return full_kernel_version, tag_version, spectarfile_release, new_tag, major_version
39+
return kernel_version, tag_version, spectarfile_release, new_tag, major_version
4240

4341

4442
def update_spec_file(
@@ -77,75 +75,49 @@ def update_spec_file(
7775

7876
# Get git user info, checking both repo-level and global config
7977
try:
80-
name = srcgit.git.config("user.name")
81-
email = srcgit.git.config("user.email")
78+
name, email = get_git_user(srcgit)
8279
except git.exc.GitCommandError as e:
8380
print("ERROR: Failed to read git config. Please ensure user.name and user.email are configured.")
8481
print(' Run: git config --global user.name "Your Name"')
8582
print(' Run: git config --global user.email "your.email@example.com"')
8683
print(f" Error details: {e}")
8784
sys.exit(1)
8885

89-
new_spec = []
86+
# Update version variables
87+
updated_spec = []
9088
for line in spec:
91-
# Update version variables
9289
if line.startswith("%define specrpmversion"):
9390
line = f"%define specrpmversion {full_kernel_version}"
94-
new_spec.append(line)
95-
continue
96-
97-
if line.startswith("%define specversion"):
91+
elif line.startswith("%define specversion"):
9892
line = f"%define specversion {full_kernel_version}"
99-
new_spec.append(line)
100-
continue
101-
102-
if line.startswith("%define tarfile_release"):
93+
elif line.startswith("%define tarfile_release"):
10394
line = f"%define tarfile_release {spectarfile_release}"
104-
new_spec.append(line)
105-
continue
106-
107-
# Replace changelog
108-
if line.startswith("%changelog"):
109-
new_spec.append(line)
110-
111-
# Generate changelog header
112-
changelog_date = time.strftime("%a %b %d %Y")
113-
changelog_header = f"* {changelog_date} {name} <{email}> - {lt_tag_version}{distlocalversion}{dist}"
114-
new_spec.append(changelog_header)
115-
new_spec.append(
116-
f"-- Rebased changes for Linux {full_kernel_version} (https://github.com/ctrliq/kernel-src-tree/releases/tag/{lt_new_tag})"
117-
)
118-
119-
# Add all commits from upstream tag to HEAD
120-
try:
121-
commit_logs = srcgit.git.log("--no-merges", "--pretty=format:-- %s (%an)", f"{upstream_tag}..HEAD")
122-
for log_line in commit_logs.split("\n"):
123-
if log_line.strip():
124-
new_spec.append(log_line)
125-
except git.exc.GitCommandError as e:
126-
print(f"ERROR: Failed to get git log from {upstream_tag}..HEAD: {e}")
127-
sys.exit(1)
95+
updated_spec.append(line)
12896

129-
new_spec.append("")
130-
new_spec.append(
131-
f"-- Linux {full_kernel_version} (https://cdn.kernel.org/pub/linux/kernel/v{lt_major_version}.x/ChangeLog-{full_kernel_version})"
132-
)
133-
new_spec.append("")
134-
new_spec.append("")
97+
# Build changelog entry lines
98+
changelog_date = time.strftime("%a %b %d %Y")
99+
changelog_lines = [
100+
f"* {changelog_date} {name} <{email}> - {lt_tag_version}{distlocalversion}{dist}",
101+
f"-- Rebased changes for Linux {full_kernel_version} (https://github.com/ctrliq/kernel-src-tree/releases/tag/{lt_new_tag})",
102+
]
135103

136-
# Preserve trailing comments from original spec file
137-
in_changelog = False
138-
for orig_line in spec:
139-
if orig_line.startswith("%changelog"):
140-
in_changelog = True
141-
continue
142-
if in_changelog and (orig_line.startswith("#") or orig_line.startswith("###")):
143-
new_spec.append(orig_line)
104+
try:
105+
commit_logs = srcgit.git.log("--no-merges", "--pretty=format:-- %s (%an)", f"{upstream_tag}..HEAD")
106+
for log_line in commit_logs.split("\n"):
107+
if log_line.strip():
108+
changelog_lines.append(log_line)
109+
except git.exc.GitCommandError as e:
110+
print(f"ERROR: Failed to get git log from {upstream_tag}..HEAD: {e}")
111+
sys.exit(1)
144112

145-
# Skip the rest of the original changelog
146-
break
113+
changelog_lines += [
114+
"",
115+
f"-- Linux {full_kernel_version} (https://cdn.kernel.org/pub/linux/kernel/v{lt_major_version}.x/ChangeLog-{full_kernel_version})",
116+
"",
117+
"",
118+
]
147119

148-
new_spec.append(line)
120+
new_spec = replace_spec_changelog(updated_spec, changelog_lines)
149121

150122
# Write the updated spec file
151123
try:
@@ -189,25 +161,15 @@ def update_spec_file(
189161
print(f"Using last tag: {upstream_tag}")
190162

191163
# Validate tag format (should be like 'v6.12.74' or '6.12.74')
192-
tag_without_v = upstream_tag.lstrip("v")
193-
tag_parts = tag_without_v.split(".")
194-
if len(tag_parts) != 3:
195-
print(f"ERROR: Invalid tag format: {upstream_tag}")
196-
print(" Expected format: vX.Y.Z or X.Y.Z (e.g., v6.12.74)")
197-
sys.exit(1)
198-
199-
# Validate that parts are numeric
200164
try:
201-
for part in tag_parts:
202-
int(part)
203-
except ValueError:
204-
print(f"ERROR: Invalid tag format: {upstream_tag}")
205-
print(" Tag version parts must be numeric")
165+
kernel_version = parse_kernel_tag(upstream_tag)
166+
except ValueError as e:
167+
print(f"ERROR: {e}")
206168
sys.exit(1)
207169

208170
# Calculate version strings
209171
full_kernel_version, tag_version, spectarfile_release, new_tag, major_version = calculate_lt_rebase_versions(
210-
upstream_tag, args.distlocalversion, args.dist
172+
kernel_version, args.distlocalversion, args.dist
211173
)
212174

213175
print("\nLT Rebase Version Information:")

0 commit comments

Comments
 (0)