Skip to content

Commit a609108

Browse files
authored
Add changelog to generate JSON metadata schema (#48)
1 parent 0df7b32 commit a609108

File tree

11 files changed

+107
-13
lines changed

11 files changed

+107
-13
lines changed

_validate/addonManifest.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class AddonManifest(ConfigObj):
3131
# Long description with further information and instructions
3232
description = string(default=None)
3333
34+
# Document changes between the previous and the current versions.
35+
changelog = string(default=None)
36+
3437
# Name of the author or entity that created the add-on
3538
author = string()
3639
@@ -89,8 +92,8 @@ def __init__(self, input: str | TextIOBase, translatedInput: str | None = None):
8992
self._translatedConfig = None
9093
if translatedInput is not None:
9194
self._translatedConfig = ConfigObj(translatedInput, encoding="utf-8", default_encoding="utf-8")
92-
for key in ("summary", "description"):
93-
val: str = self._translatedConfig.get(key) # type: ignore[reportUnknownMemberType]
95+
for key in ("summary", "description", "changelog"):
96+
val: str | None = self._translatedConfig.get(key) # type: ignore[reportUnknownMemberType]
9497
if val:
9598
self[key] = val
9699

_validate/addonVersion_schema.json

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
"sourceURL": "https://github.com/nvaccess/addon-datastore/",
2929
"license": "GPL v2",
3030
"licenseURL": "https://github.com/nvaccess/addon-datastore/license.MD",
31+
"changelog": "New features",
3132
"translations": [
3233
{
3334
"language": "de",
3435
"displayName": "Mein Addon",
35-
"description": "erleichtert das Durchführen von xyz"
36+
"description": "erleichtert das Durchführen von xyz",
37+
"changelog": "Neue Funktionen"
3638
}
3739
],
3840
"reviewUrl": "https://github.com/nvaccess/addon-datastore/discussions/1942#discussioncomment-7453248",
@@ -228,6 +230,16 @@
228230
"title": "The URL of the license",
229231
"type": "string"
230232
},
233+
"changelog": {
234+
"$id": "#/properties/changelog",
235+
"default": "",
236+
"description": "Changes between the previous and the current version",
237+
"examples": [
238+
"New feature"
239+
],
240+
"title": "Add-on changelog (en)",
241+
"type": "string"
242+
},
231243
"legacy": {
232244
"$id": "#/properties/legacy",
233245
"default": false,
@@ -247,7 +259,8 @@
247259
{
248260
"language": "de",
249261
"displayName": "Mein Addon",
250-
"description": "erleichtert das Durchführen von xyz"
262+
"description": "erleichtert das Durchführen von xyz",
263+
"changelog": "Neue Funktionen"
251264
}
252265
]
253266
],
@@ -357,7 +370,8 @@
357370
{
358371
"language": "de",
359372
"displayName": "Mein Addon",
360-
"description": "erleichtert das Durchführen von xyz"
373+
"description": "erleichtert das Durchführen von xyz",
374+
"changelog": "Neue Funktionen"
361375
}
362376
],
363377
"required": [
@@ -393,6 +407,15 @@
393407
],
394408
"title": "The translated description",
395409
"type": "string"
410+
},
411+
"changelog": {
412+
"default": "",
413+
"description": "Translated description of changes between the previous and this add-on version",
414+
"examples": [
415+
"Neue Funktionen"
416+
],
417+
"title": "The translated changelog",
418+
"type": "string"
396419
}
397420
}
398421
}

_validate/createJson.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ class AddonData:
3232
sourceURL: str
3333
license: str
3434
homepage: str | None
35+
changelog: str | None
3536
licenseURL: str | None
3637
submissionTime: int
37-
translations: list[dict[str, str]]
38+
translations: list[dict[str, str | None]]
3839

3940

4041
def getSha256(addonPath: str) -> str:
@@ -108,17 +109,31 @@ def _createDataclassMatchingJsonSchema(
108109

109110
# Add optional fields
110111
homepage: str | None = manifest.get("url") # type: ignore[reportUnknownMemberType]
111-
if not homepage or homepage == "None":
112+
if homepage == "None":
113+
# The config default is None
114+
# which is parsed by configobj as a string not a NoneType
112115
homepage = None
113-
114-
translations: list[dict[str, str]] = []
116+
changelog: str | None = manifest.get("changelog") # type: ignore[reportUnknownMemberType]
117+
if changelog == "None":
118+
# The config default is None
119+
# which is parsed by configobj as a string not a NoneType
120+
changelog = None
121+
translations: list[dict[str, str | None]] = []
115122
for langCode, translatedManifest in getAddonManifestLocalizations(manifest):
123+
# Add optional translated changelog.
124+
translatedChangelog: str | None = translatedManifest.get("changelog") # type: ignore[reportUnknownMemberType]
125+
if translatedChangelog == "None":
126+
# The config default is None
127+
# which is parsed by configobj as a string not a NoneType
128+
translatedChangelog = None
129+
116130
try:
117131
translations.append(
118132
{
119133
"language": langCode,
120134
"displayName": cast(str, translatedManifest["summary"]),
121135
"description": cast(str, translatedManifest["description"]),
136+
"changelog": translatedChangelog,
122137
},
123138
)
124139
except KeyError as e:
@@ -141,6 +156,7 @@ def _createDataclassMatchingJsonSchema(
141156
sourceURL=sourceUrl,
142157
license=licenseName,
143158
homepage=homepage,
159+
changelog=changelog,
144160
licenseURL=licenseUrl,
145161
submissionTime=getCurrentTime(),
146162
translations=translations,

_validate/regenerateTranslations.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,23 @@ def regenerateJsonFile(filePath: str, errorFilePath: str | None) -> None:
2323
with open(errorFilePath, "w") as errorFile:
2424
errorFile.write(f"Validation Errors:\n{manifest.errors}")
2525
return
26-
26+
changelog = manifest.get("changelog") # type: ignore[reportUnknownMemberType]
27+
if changelog == "None":
28+
# The config default is None
29+
# which is parsed by configobj as a string not a NoneType
30+
changelog = None
2731
for langCode, manifest in getAddonManifestLocalizations(manifest):
32+
translatedChangelog = manifest.get("changelog") # type: ignore[reportUnknownMemberType]
33+
if translatedChangelog == "None":
34+
# The config default is None
35+
# which is parsed by configobj as a string not a NoneType
36+
translatedChangelog = None
2837
addonData["translations"].append(
2938
{
3039
"language": langCode,
3140
"displayName": manifest["summary"],
3241
"description": manifest["description"],
42+
"changelog": translatedChangelog,
3343
},
3444
)
3545

_validate/validate.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ def checkDescriptionMatches(manifest: AddonManifest, submission: JsonObjT) -> Va
134134
)
135135

136136

137+
def checkChangelogMatches(manifest: AddonManifest, submission: JsonObjT) -> ValidationErrorGenerator:
138+
"""The submission changelog must match the *.nvda-addon manifest changelog field."""
139+
changelog = manifest.get("changelog") # type: ignore[reportUnknownMemberType]
140+
if changelog == "None":
141+
# The config default is None which is parsed by configobj as a string not a NoneType
142+
changelog = None
143+
if changelog != submission.get("changelog"):
144+
yield (
145+
f"Submission 'changelog' must be set to '{manifest.get('changelog')}' " # type: ignore[reportUnknownMemberType]
146+
f"in json file instead of {submission.get('changelog')}"
147+
)
148+
149+
137150
def checkUrlMatchesHomepage(manifest: AddonManifest, submission: JsonObjT) -> ValidationErrorGenerator:
138151
"""The submission homepage must match the *.nvda-addon manifest url field."""
139152
manifestUrl = manifest.get("url") # type: ignore[reportUnknownMemberType]
@@ -332,6 +345,7 @@ def validateSubmission(submissionFilePath: str, verFilename: str) -> ValidationE
332345
manifest = getAddonManifest(addonDestPath)
333346
yield from checkSummaryMatchesDisplayName(manifest, submissionData)
334347
yield from checkDescriptionMatches(manifest, submissionData)
348+
yield from checkChangelogMatches(manifest, submissionData)
335349
yield from checkUrlMatchesHomepage(manifest, submissionData)
336350
yield from checkAddonId(manifest, submissionFilePath, submissionData)
337351
yield from checkMinNVDAVersionMatches(manifest, submissionData)

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ reportMissingTypeStubs = false
6767

6868
[tool.uv]
6969
default-groups = "all"
70-
python-preference = "only-system"
7170
environments = ["sys_platform == 'win32'"]
7271
required-version = ">=0.8"
7372

tests/testData/addons/fake/13.0.0.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
},
99
"displayName": "mock addon",
1010
"description": "The description for the addon",
11+
"changelog": "Changes for this add-on version",
1112
"homepage": "https://nvaccess.org",
1213
"publisher": "Name of addon author or organisation",
1314
"minNVDAVersion": {
@@ -23,7 +24,7 @@
2324
"channel": "stable",
2425
"URL": "https://github.com/nvaccess/dont/use/this/address/fake.nvda-addon",
2526
"sha256-comment": "SHA for the fake.nvda-addon file",
26-
"sha256": "e27fa778cb99f83ececeb0bc089033929eab5a2fa475ce63e68f50b03b6ab585",
27+
"sha256": "50a8011a807665bcb8fdd177c276fef3b3f7f754796c5990ebe14e80c28b14ef",
2728
"sourceURL": "https://github.com/nvaccess/dont/use/this/address",
2829
"license": "GPL v2",
2930
"licenseURL": "https://www.gnu.org/licenses/gpl-2.0.html",

tests/testData/fake.nvda-addon

57 Bytes
Binary file not shown.

tests/testData/manifest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name = fake
22
summary = "mock addon"
33
description = """The description for the addon"""
4+
changelog = """Changes for this add-on version"""
45
author = "Name of addon author or organisation"
56
url = https://nvaccess.org
67
version = 13.0

tests/test_createJson.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def test_validVersion(self):
9999
sourceURL="https://example.com",
100100
license="GPL v2",
101101
homepage="https://example.com",
102+
changelog="""Changes for this add-on version""",
102103
licenseURL="https://www.gnu.org/licenses/gpl-2.0.html",
103104
submissionTime=createJson.getCurrentTime(),
104105
translations=[],

0 commit comments

Comments
 (0)