e955c94ed3
Listing the "Blender Foundation" as copyright holder implied the Blender Foundation holds copyright to files which may include work from many developers. While keeping copyright on headers makes sense for isolated libraries, Blender's own code may be refactored or moved between files in a way that makes the per file copyright holders less meaningful. Copyright references to the "Blender Foundation" have been replaced with "Blender Authors", with the exception of `./extern/` since these this contains libraries which are more isolated, any changed to license headers there can be handled on a case-by-case basis. Some directories in `./intern/` have also been excluded: - `./intern/cycles/` it's own `AUTHORS` file is planned. - `./intern/opensubdiv/`. An "AUTHORS" file has been added, using the chromium projects authors file as a template. Design task: #110784 Ref !110783.
172 lines
5.9 KiB
Python
172 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-FileCopyrightText: 2023 Blender Authors
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import requests
|
|
|
|
|
|
class ReleaseLogLine:
|
|
"""
|
|
Class containing the information of a single line of the release log
|
|
|
|
Instance attributes:
|
|
|
|
* line: (str) the original line used to create this log line
|
|
* issue_id: (int or None) the extracted issue id associated with this log
|
|
line. Can be None if the log line isn't associated with a issue.
|
|
* commit_id: (str or None) the extracted commit id associated with this log
|
|
line. Only filled when no `issue_id` could be found.
|
|
* ref: (str) `issue_id` or `commit_id` of this line, including `T` for issues
|
|
or `D` for diffs.
|
|
* title: (str) title of this log line. When constructed this attribute is
|
|
an empty string. The called needs to retrieve the title from the
|
|
backend.
|
|
* url: (str) url of the ticket issue or commit.
|
|
"""
|
|
|
|
def __init__(self, line: str):
|
|
self.line = line
|
|
items = line.split("|")
|
|
self.issue_id = None
|
|
self.issue_repo = None
|
|
self.commit_id = None
|
|
self.commit_repo = None
|
|
base_url = "https://projects.blender.org"
|
|
try:
|
|
issue_tokens = items[1].strip().split("#")
|
|
if len(issue_tokens[0]) > 0:
|
|
self.issue_repo = issue_tokens[0]
|
|
self.issue_id = issue_tokens[1]
|
|
else:
|
|
self.issue_repo = "blender/blender"
|
|
self.issue_id = issue_tokens[1]
|
|
|
|
self.ref = f"#{self.issue_id}"
|
|
self.url = f"{base_url}/{self.issue_repo}/issues/{self.issue_id}"
|
|
except IndexError:
|
|
# no issue
|
|
commit_string = items[3].strip()
|
|
commit_string = commit_string.split(",")[0]
|
|
commit_string = commit_string.split("]")[0]
|
|
commit_string = commit_string.replace("[", "")
|
|
|
|
commit_tokens = commit_string.split("@")
|
|
if len(commit_tokens) > 1:
|
|
self.commit_repo = commit_tokens[0]
|
|
self.commit_id = commit_tokens[1]
|
|
else:
|
|
self.commit_repo = "blender/blender"
|
|
self.commit_id = commit_tokens[0]
|
|
|
|
self.ref = f"{self.commit_id}"
|
|
self.url = f"{base_url}/{self.commit_repo}/commit/{self.commit_id}"
|
|
|
|
self.title = ""
|
|
|
|
def __format_as_html(self) -> str:
|
|
return f" <li>{self.title} [<a href=\"{self.url}\">{self.ref}</a>]</li>"
|
|
|
|
def __format_as_text(self) -> str:
|
|
return f"* {self.title} [{self.ref}]"
|
|
|
|
def __format_as_steam(self) -> str:
|
|
return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
|
|
|
|
def __format_as_wiki(self) -> str:
|
|
if self.issue_id:
|
|
return f"* {self.title} [{{{{BugReport|{self.issue_id}}}}}]"
|
|
else:
|
|
return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
|
|
|
|
def format(self, format: str) -> str:
|
|
"""
|
|
Format this line
|
|
|
|
:attr format: the desired format. Possible values are 'text', 'steam' or 'html'
|
|
:type string:
|
|
"""
|
|
if format == 'html':
|
|
return self.__format_as_html()
|
|
elif format == 'steam':
|
|
return self.__format_as_steam()
|
|
elif format == 'wiki':
|
|
return self.__format_as_wiki()
|
|
else:
|
|
return self.__format_as_text()
|
|
|
|
|
|
def format_title(title: str) -> str:
|
|
title = title.strip()
|
|
if not title.endswith("."):
|
|
title = title + "."
|
|
return title
|
|
|
|
|
|
def extract_release_notes(version: str, issue: str):
|
|
"""
|
|
Extract all release notes logs
|
|
|
|
# Process
|
|
|
|
1. Retrieval of description of the given `issue_id`.
|
|
2. Find rows for the given `version` and convert to `ReleaseLogLine`.
|
|
3. based on the associated issue or commit retrieves the title of the log
|
|
line.
|
|
"""
|
|
base_url = "https://projects.blender.org/api/v1/repos"
|
|
issues_url = base_url + "/blender/blender/issues/"
|
|
headers = {'accept': 'application/json'}
|
|
|
|
response = requests.get(issues_url + issue[1:], headers=headers)
|
|
description = response.json()["body"]
|
|
|
|
lines = description.split("\n")
|
|
start_index = lines.index(f"## Blender {version}")
|
|
lines = lines[start_index + 1:]
|
|
for line in lines:
|
|
if not line.strip():
|
|
continue
|
|
if line.startswith("| **Report**"):
|
|
continue
|
|
if line.startswith("## Blender"):
|
|
break
|
|
if line.find("| -- |") != -1:
|
|
continue
|
|
|
|
log_line = ReleaseLogLine(line)
|
|
if log_line.issue_id:
|
|
issue_url = f"{base_url}/{log_line.issue_repo}/issues/{log_line.issue_id}"
|
|
response = requests.get(issue_url, headers=headers)
|
|
if response.status_code != 200:
|
|
raise ValueError("Issue not found: " + str(log_line.issue_id))
|
|
|
|
log_line.title = format_title(response.json()["title"])
|
|
yield log_line
|
|
elif log_line.commit_id:
|
|
commit_url = f"{base_url}/{log_line.commit_repo}/git/commits/{log_line.commit_id}"
|
|
response = requests.get(commit_url, headers=headers)
|
|
if response.status_code != 200:
|
|
raise ValueError("Commit not found: " + log_line.commit_id)
|
|
|
|
commit_message = response.json()['commit']['message']
|
|
commit_title = commit_message.split("\n")[0]
|
|
log_line.title = format_title(commit_title)
|
|
yield log_line
|
|
|
|
|
|
def print_notes(version: str, format: str, issue: str):
|
|
"""
|
|
Generate and print the release notes to the console.
|
|
"""
|
|
if format == 'html':
|
|
print("<ul>")
|
|
if format == 'steam':
|
|
print("[ul]")
|
|
for log_item in extract_release_notes(version=version, issue=issue):
|
|
print(log_item.format(format=format))
|
|
if format == 'html':
|
|
print("</ul>")
|
|
if format == 'steam':
|
|
print("[/ul]")
|