mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-10-26 19:15:09 +00:00
Rewrite update-since-todo.sh in Python (#6458)
This commit is contained in:
1 parent
f4b4aa853b
commit
212ee6bbcf
2 files changed
+131
-59
No files matched your search
Executable
+131
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import fileinput
|
||||
import io
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
GIT = shutil.which("git")
|
||||
|
||||
|
||||
def update_file(file, lineno, old, new):
|
||||
"""
|
||||
Replace all occurrences of the old substring by the new substring.
|
||||
|
||||
:param file: The file to update.
|
||||
:param lineno: The line number to update.
|
||||
:param old: The old substring.
|
||||
:param new: The new substring.
|
||||
"""
|
||||
print("\tUpdating file in place")
|
||||
with fileinput.FileInput(file, inplace=True) as f:
|
||||
for line in f:
|
||||
if f.lineno() == lineno and old in line:
|
||||
print(line.replace(old, new), end="")
|
||||
else:
|
||||
print(line, end="")
|
||||
|
||||
|
||||
def analyze_file(file, lineno, commits_and_tags, dry_run=False):
|
||||
"""
|
||||
Analyze the given file.
|
||||
|
||||
:param file: The file to analyze.
|
||||
:param lineno: The line number to analyze.
|
||||
:param commits_and_tags: The output dictionary mapping commits to release tags.
|
||||
:param dry_run: Whether or not this is a dry run.
|
||||
"""
|
||||
print(f"Analyzing {file}:{lineno}")
|
||||
line_sha = (
|
||||
subprocess.check_output(
|
||||
[GIT, "blame", "--porcelain", "-L", f"{lineno},{lineno}", file], text=True
|
||||
)
|
||||
.split("\n", 1)[0]
|
||||
.split(" ", 1)[0]
|
||||
)
|
||||
print(f"\tfirst sha: {line_sha}")
|
||||
first_tag = subprocess.check_output(
|
||||
[GIT, "tag", "--sort=creatordate", "--contains", line_sha, "jenkins-*"],
|
||||
text=True,
|
||||
).split("\n", 1)[0]
|
||||
if first_tag:
|
||||
print(f"\tfirst tag was {first_tag}")
|
||||
commits_and_tags[line_sha] = first_tag
|
||||
if not dry_run:
|
||||
update_file(
|
||||
file,
|
||||
int(lineno),
|
||||
"@since TODO",
|
||||
"@since " + first_tag.replace("jenkins-", ""),
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"\tNot updating file, no tag found. "
|
||||
"Normal if the associated PR/commit is not merged and released yet; "
|
||||
"otherwise make sure to fetch tags from jenkinsci/jenkins"
|
||||
)
|
||||
|
||||
|
||||
def analyze_files(commits_and_tags, dry_run=False):
|
||||
"""
|
||||
Analyze all files in the repository.
|
||||
|
||||
:param commits_and_tags: The output dictionary mapping commits to release tags.
|
||||
:param dry_run: Whether or not this is a dry run.
|
||||
"""
|
||||
cmd = [
|
||||
GIT,
|
||||
"grep",
|
||||
"--line-number",
|
||||
"@since TODO",
|
||||
"--",
|
||||
"*.java",
|
||||
"*.jelly",
|
||||
"*.js",
|
||||
]
|
||||
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc:
|
||||
for line in io.TextIOWrapper(proc.stdout):
|
||||
parts = line.rstrip().split(":", 2)
|
||||
analyze_file(parts[0], parts[1], commits_and_tags, dry_run=dry_run)
|
||||
retcode = proc.wait()
|
||||
if retcode:
|
||||
raise subprocess.CalledProcessError(retcode, cmd)
|
||||
print()
|
||||
|
||||
|
||||
def display_results(commits_and_tags):
|
||||
"""
|
||||
Display the results of the analysis.
|
||||
|
||||
:param commits_and_tags: The output dictionary mapping commits to release tags.
|
||||
"""
|
||||
print("List of commits introducing new API and the first release they went in:")
|
||||
releases = {release for release in commits_and_tags.values()}
|
||||
for release in sorted(releases):
|
||||
print(f"* https://github.com/jenkinsci/jenkins/releases/tag/{release}")
|
||||
for commit, first_release in commits_and_tags.items():
|
||||
if release == first_release:
|
||||
print(f" - https://github.com/jenkinsci/jenkins/commit/{commit}")
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Update '@since TODO' entries with actual Jenkins release versions.
|
||||
|
||||
This script is a developer tool, to be used by maintainers.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Update '@since TODO' entries with actual Jenkins release versions."
|
||||
)
|
||||
parser.add_argument("-n", "--dry-run", help="Dry run", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
commits_and_tags = {}
|
||||
analyze_files(commits_and_tags, dry_run=args.dry_run)
|
||||
if commits_and_tags:
|
||||
display_results(commits_and_tags)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script is a developer tool, to be used by maintainers
|
||||
# to update '@since TODO' entries with actual Jenkins release versions.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Needs bash 4+
|
||||
declare -A commitsAndTags
|
||||
|
||||
IFS=$'\n'
|
||||
for todo in $( git grep --line-number '@since TODO' -- *.java *.jelly *.js)
|
||||
do
|
||||
#echo "TODO: $todo"
|
||||
file=$( echo "$todo" | cut -d : -f 1 )
|
||||
line=$( echo "$todo" | cut -d : -f 2 )
|
||||
|
||||
echo "Analyzing $file:$line"
|
||||
|
||||
lineSha=$( git blame --porcelain -L "$line,$line" "$file" | head -1 | cut -d ' ' -f 1 )
|
||||
echo -e "\tfirst sha: $lineSha"
|
||||
|
||||
firstTag=$( git tag --sort=creatordate --contains "$lineSha" 'jenkins-*' | head -1 )
|
||||
|
||||
if [[ -n $firstTag ]]; then
|
||||
echo -e "\tfirst tag was $firstTag"
|
||||
commitsAndTags[$lineSha]="$firstTag"
|
||||
echo -e "\tUpdating file in place"
|
||||
sedExpr="${line}s/@since TODO/@since ${firstTag//jenkins-/}/"
|
||||
sed -i.bak "$sedExpr" "$file"
|
||||
rm -f "$file.bak"
|
||||
else
|
||||
echo -e "\tNot updating file, no tag found. Normal if the associated PR/commit is not merged and released yet; otherwise make sure to fetch tags from jenkinsci/jenkins"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${#commitsAndTags[@]}" -gt 0 ]] ; then
|
||||
echo ''
|
||||
echo "List of commits introducing new API and the first release they went in:"
|
||||
declare -A releases
|
||||
for commit in "${!commitsAndTags[@]}" ; do
|
||||
release="${commitsAndTags[$commit]}"
|
||||
releases[$release]=1
|
||||
done
|
||||
|
||||
mapfile -t sortedReleases < <( sort <<<"${!releases[*]}" )
|
||||
|
||||
for release in "${sortedReleases[@]}" ; do
|
||||
echo "* https://github.com/jenkinsci/jenkins/releases/tag/${release}"
|
||||
for commit in "${!commitsAndTags[@]}" ; do
|
||||
firstRelease="${commitsAndTags[$commit]}"
|
||||
if [[ "$release" = "$firstRelease" ]] ; then
|
||||
echo " - https://github.com/jenkinsci/jenkins/commit/$commit"
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
Reference in new issue
Block a user