From ad75c971d67746391578328048fb13bd807434b4 Mon Sep 17 00:00:00 2001 From: Aurelien Gateau Date: Sun, 2 Apr 2023 12:23:53 +0200 Subject: [PATCH 1/3] linux install: add an appstream file --- README.md | 2 +- src/CMakeLists.txt | 4 +++ src/linux/nanonote.metainfo.xml | 60 +++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/linux/nanonote.metainfo.xml diff --git a/README.md b/README.md index ea7b6ba..86bcaf9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Nanonote is a minimalist note taking application. ![Screenshot](screenshot.png) -It automatically saves anything you type. Being minimalist means it has no synchronisation, does not support multiple documents, images or any advanced formatting (the only formatting is highlighting URLs). +It automatically saves anything you type. Being minimalist means it has no synchronisation, does not support multiple documents, images or any advanced formatting (the only formatting is highlighting URLs and Markdown-like headings). It is developed and tested on Linux but also works on macOS and Windows as well. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e2b0708..ff7efe0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -100,6 +100,10 @@ if (UNIX AND NOT APPLE) DESTINATION share/applications RENAME ${INVERSE_ORGANIZATION_NAME}.${APP_NAME}.desktop ) + install(FILES linux/${APP_NAME}.metainfo.xml + DESTINATION share/metainfo + RENAME ${INVERSE_ORGANIZATION_NAME}.${APP_NAME}.metainfo.xml + ) endif() if (WIN32) diff --git a/src/linux/nanonote.metainfo.xml b/src/linux/nanonote.metainfo.xml new file mode 100644 index 0000000..7f32c66 --- /dev/null +++ b/src/linux/nanonote.metainfo.xml @@ -0,0 +1,60 @@ + + + + com.agateau.Nanonote + CC0-1.0 + + Nanonote + + + A minimalist note taking application. + + + +

+ Nanonote is a minimalist note taking application. +

+

+ It automatically saves anything you type. Being minimalist means it has no synchronisation, does not support multiple documents, images or any advanced formatting (the only formatting is highlighting URLs and Markdown-like headings). + Pixel Wheels is a retro top-down race game for Linux, macOS, Windows and Android. +

+
+ + + Utility + TextEditor + + + https://agateau.com/projects/nanonote + https://github.com/agateau/nanonote/issues + https://agateau.com/support + + com.agateau.nanonote.desktop + + + + + + + + + + + + + + nanonote + + + GPL-3.0-or-later + + + + https://github.com/agateau/nanonote/raw/1.3.91/screenshot.png + + + + +
From 2505cc2e657044d1e5657a6fdc3a3208d0d199fb Mon Sep 17 00:00:00 2001 From: Aurelien Gateau Date: Sun, 2 Apr 2023 13:04:24 +0200 Subject: [PATCH 2/3] release: Add changelog parser --- CHANGELOG.md | 4 ++- changelog.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tasks.py | 25 ++++++++++++------ 3 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 changelog.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e58f2fd..9d5012c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,4 +93,6 @@ ## 1.0.0 - 2018-12-30 -First release +### Added + +- First release diff --git a/changelog.py b/changelog.py new file mode 100644 index 0000000..e60e0ac --- /dev/null +++ b/changelog.py @@ -0,0 +1,72 @@ +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any, Iterable + + +@dataclass +class Release: + version: str + date: str + # type => [changes] + changes: dict[str, list[str]] = field(default_factory=dict) + + +@dataclass +class Changelog: + # version => release + releases: dict[str, Release] = field(default_factory=dict) + + @staticmethod + def from_path(changelog_path: Path) -> "Changelog": + with changelog_path.open() as f: + parser = Parser(f) + return parser.parse() + + +def _get_dict_last_added_item(dct: dict[Any, Any]) -> Any: + return list(dct.values())[-1] + + +class Parser: + def __init__(self, line_it: Iterable[str]): + self.changelog = Changelog() + self.line_it = line_it + + def parse(self) -> Changelog: + self._parser = self._parse_prolog + for line in self.line_it: + line = line.strip() + if line: + self._parser(line) + + return self.changelog + + def _parse_prolog(self, line: str) -> None: + if line.startswith("## "): + self._parse_release_title(line) + self._parser = self._parse_release_content + + def _parse_release_title(self, line: str) -> None: + version, date = line[3:].split(" - ", maxsplit=1) + release = Release(version=version, date=date) + self.changelog.releases[version] = release + + def _parse_release_content(self, line: str) -> None: + if line.startswith("## "): + self._parse_release_title(line) + return + + release = _get_dict_last_added_item(self.changelog.releases) + + if line.startswith("### "): + change_type = line[4:] + release.changes[change_type] = [] + else: + assert line.startswith("- "), line + current_changes = _get_dict_last_added_item(release.changes) + current_changes.append(line[2:]) + + +if __name__ == "__main__": + changelog = Changelog.from_path(Path("CHANGELOG.md")) + print(changelog) diff --git a/tasks.py b/tasks.py index 5bd8312..8168310 100644 --- a/tasks.py +++ b/tasks.py @@ -9,9 +9,13 @@ from invoke import task, run +from changelog import Changelog, Release + ARTIFACTS_DIR = Path("artifacts") +CHANGELOG_MD = Path("CHANGELOG.md") + MAIN_BRANCH = "master" @@ -145,23 +149,28 @@ def download_artifacts(c): erun(f"gh run download --dir {ARTIFACTS_DIR}", pty=True) -def prepare_release_notes(version_md: Path) -> str: +def prepare_release_notes(release: Release) -> str: """ - Take the content of $VERSION.md and return it ready to use as GitHub release notes: - - Remove header - - Turn all h3 into h2 + Take a Release instance and produce markdown suitable for GitHub release + notes """ - content = re.sub("^## .*", "", version_md.read_text()) - content = re.sub("^### ", "## ", content, flags=re.MULTILINE) - return content.strip() + "\n" + lines = [] + for change_type, changes in release.changes.items(): + lines.append(f"## {change_type}") + for change in changes: + lines.append(f"- {change}") + return "\n\n".join(lines) + "\n" @task(help={"pre": "This is a prerelease"}) def publish(c, pre=False): version = get_version() + changelog = Changelog.from_path(CHANGELOG_MD) + release = changelog.releases[version] + content = prepare_release_notes(release) + files_str = " ".join(str(x) for x in get_artifact_list()) with NamedTemporaryFile() as tmp_file: - content = prepare_release_notes(Path(".changes") / f"{version}.md") tmp_file.write(content.encode("utf-8")) tmp_file.flush() cmd = f"gh release create {version} -F{tmp_file.name} {files_str}" From beab53e25c63d9b25178faf5bc530e14c24fb870 Mon Sep 17 00:00:00 2001 From: Aurelien Gateau Date: Sun, 2 Apr 2023 13:18:22 +0200 Subject: [PATCH 3/3] release: Update appstream releases tag from CHANGELOG.md --- src/linux/nanonote.metainfo.xml | 162 +++++++++++++++++++++++++++----- tasks.py | 41 ++++++++ 2 files changed, 182 insertions(+), 21 deletions(-) diff --git a/src/linux/nanonote.metainfo.xml b/src/linux/nanonote.metainfo.xml index 7f32c66..729a15f 100644 --- a/src/linux/nanonote.metainfo.xml +++ b/src/linux/nanonote.metainfo.xml @@ -3,13 +3,10 @@ com.agateau.Nanonote CC0-1.0 - Nanonote - A minimalist note taking application. -

Nanonote is a minimalist note taking application. @@ -19,42 +16,165 @@ Pixel Wheels is a retro top-down race game for Linux, macOS, Windows and Android.

- Utility TextEditor - https://agateau.com/projects/nanonote https://github.com/agateau/nanonote/issues https://agateau.com/support - com.agateau.nanonote.desktop - - - - - - - - - + + +

+ Added +

+
    +
  • Add support for Markdown-style tasks in lists (Daniel Laidig)
  • +
  • Add tips page (Aurelien Gateau)
  • +
+

+ Changed +

+
    +
  • Use Ctrl+G to open links and Ctrl+Enter for tasks (Daniel Laidig)
  • +
+

+ Fixed +

+
    +
  • Make sure standard actions like Copy or Paste are translated (Aurelien Gateau)
  • +
  • Show keyboard shortcuts in context menus on macOS (Daniel Laidig)
  • +
  • Do not change cursor to pointing-hand when not over a link (Aurelien Gateau)
  • +
+

+ Internals +

+
    +
  • CI: Bump Ubuntu to 20.04 and macOS to 11 (Aurelien Gateau)
  • +
  • CI: Install clang-format from muttleyxd/clang-tools-static-binaries (Aurelien Gateau)
  • +
  • Bump Qt to 5.15.2 on macOS and Windows (Aurelien Gateau)
  • +
  • Update singleaplication to 3.3.4 (Aurelien Gateau)
  • +
  • Update Catch2 to 3.3.0 (Aurelien Gateau)
  • +
+
+
+ + +

+ Changed +

+
    +
  • Update Spanish translation (Victorhck)
  • +
+

+ Fixed +

+
    +
  • Properly encode URL of the note path (Aurelien Gateau)
  • +
  • Fix untranslated text in About tab on Linux (Aurelien Gateau)
  • +
+
+
+ + +

+ Added +

+
    +
  • You can now search inside your notes with the new search bar (Pavol Oresky)
  • +
  • You can now move selected lines up and down with Alt+Shift+Up and Down (Aurelien Gateau)
  • +
  • macOS dmg (Aurelien Gateau)
  • +
  • Windows installer (Aurelien Gateau)
  • +
+

+ Changed +

+
    +
  • Reorganized context menu: added "Edit" and "View" submenus (Aurelien Gateau)
  • +
+
+
+ + +

+ Added +

+
    +
  • New German translation by Vinzenz Vietzke
  • +
  • Allow changing the font size using Ctrl + mouse wheel (Daniel Laidig)
  • +
  • Use the link color of the color theme instead of an hardcoded blue (Daniel Laidig)
  • +
  • Added a way to reset the font size to the default value (Daniel Laidig)
  • +
+

+ Fixed +

+
    +
  • Added explanation of how to open URLs to the welcome text (Robert Barat)
  • +
  • Allow '@' in URLs (Aurelien Gateau)
  • +
  • Use QSaveFile for safer saving (Aurelien Gateau)
  • +
+
+
+ + +

+ Added +

+
    +
  • Pressing tab now indents the whole line when the cursor is at the beginning of a list item (Daniel Laidig).
  • +
  • Pressing Enter on an empty list item now unindents, then removes the bullet (Aurelien Gateau).
  • +
  • Added French and Spanish translations (Aurelien Gateau, Victorhck).
  • +
+

+ Fixed +

+
    +
  • Improved url detection: '+', '%' and '~' are now allowed in the middle of urls (Aurelien Gateau).
  • +
  • Fixed wrong indentation behavior in upward selections (Aurelien Gateau).
  • +
+
+
+ + +

+ Added +

+
    +
  • Added unit-tests.
  • +
  • Added Travis integration.
  • +
  • Added rpm and deb packages generated using CPack.
  • +
+

+ Fixed +

+
    +
  • Fixed indentation and make it respect indentation columns.
  • +
  • Made it possible to indent/unindent selected lines with Tab/Shift+Tab.
  • +
  • Update welcome text to reflect current shortcuts.
  • +
+
+
+ + +

+ Added +

+
    +
  • First release
  • +
+
+
- nanonote - GPL-3.0-or-later - https://github.com/agateau/nanonote/raw/1.3.91/screenshot.png -
diff --git a/tasks.py b/tasks.py index 8168310..bc8a5ad 100644 --- a/tasks.py +++ b/tasks.py @@ -1,7 +1,9 @@ import os import re import shutil +import subprocess import sys +import xml.etree.ElementTree as ET from pathlib import Path from tempfile import NamedTemporaryFile @@ -15,6 +17,7 @@ ARTIFACTS_DIR = Path("artifacts") CHANGELOG_MD = Path("CHANGELOG.md") +APPSTREAM_XML = Path("src/linux/nanonote.metainfo.xml") MAIN_BRANCH = "master" @@ -68,6 +71,42 @@ def update_version(c): path.write_text(text) +@task +def update_appstream_releases(c): + """Regenerate the element of our appstream file from + CHANGELOG.md""" + changelog = Changelog.from_path(CHANGELOG_MD) + + releases_et = ET.Element("releases") + for release in changelog.releases.values(): + release_et = ET.SubElement(releases_et, "release", + { + "version": release.version, + "date": release.date + }) + description_et = ET.SubElement(release_et, "description") + for change_type, changes in release.changes.items(): + p_et = ET.SubElement(description_et, "p") + em_et = ET.SubElement(p_et, "em") + em_et.text = change_type + ul_et = ET.SubElement(description_et, "ul") + for change in changes: + li_et = ET.SubElement(ul_et, "li") + li_et.text = change + content = ET.tostring(releases_et, encoding="unicode") + + # Replace the element by hand to avoid loosing comments, if any + appstream_content = APPSTREAM_XML.read_text() + appstream_content, count = re.subn(".*", + content, + appstream_content, flags=re.DOTALL) + assert count == 1 + subprocess.run(["xmllint", "--format", "--output", APPSTREAM_XML, "-"], + check=True, + text=True, + input=appstream_content) + + @task def create_release_branch(c): version = get_version() @@ -102,6 +141,8 @@ def create_release_branch2(c): if not is_ok("Looks good?"): sys.exit(1) + update_appstream_releases(c) + @task def update_ts(c):