From a32c9b61eef3dfa15c6c489471589f23f6a61832 Mon Sep 17 00:00:00 2001 From: Helge Date: Fri, 27 Oct 2023 13:42:33 +0200 Subject: [PATCH] Improve creation of README.md This resolves: https://codeberg.org/fediverse/fep/issues/198 --- scripts/backmatter.md | 16 +++++- scripts/create_readme.py | 47 +--------------- scripts/frontmatter.md | 1 - scripts/tools/__init__.py | 104 +++++++++++++++-------------------- scripts/tools/fep_file.py | 67 ++++++++++++++++++++++ scripts/tools/test_readme.py | 13 +++++ 6 files changed, 140 insertions(+), 108 deletions(-) create mode 100644 scripts/tools/fep_file.py create mode 100644 scripts/tools/test_readme.py diff --git a/scripts/backmatter.md b/scripts/backmatter.md index dc30b88..bf744c0 100644 --- a/scripts/backmatter.md +++ b/scripts/backmatter.md @@ -8,19 +8,29 @@ To create and submit a FEP: 1. Fork this repository, and then clone it to your local machine. Check the Codeberg [Cheat sheet](https://docs.codeberg.org/collaborating/pull-requests-and-git-flow/#cheat-sheet) on how to prepare your Pull Request. 2. Think of a title for the FEP you want to submit. 3. Compute the identifier of the FEP by computing the hash of the title. This can be done with following Unix command: + ``` $ echo -n "The title of my proposal" | sha256sum | cut -c-4 b3f0 ``` + 4. Create a subdirectory of [`fep/`](./fep/) using the identifier you just computed. 5. Copy the FEP template ([fep-xxxx-template.md](./fep-xxxx-template.md)) to this subdirectory and change the filename appropriately. -6. Use the identifer as the "slug" when filling out the frontmatter. - +6. Use the identifer as the "slug" when filling out the frontmatter. + - For example, if your computed identifier was `abcd`, then your file would be located at `fep/abcd/fep-abcd.md` and your frontmatter would include `slug: "abcd"`. 7. Write down your idea in the newly created file and commit it to a new branch in your repository (ex. fep-xxxx). 8. Create a Pull Request to complete Step 1 of [FEP-a4ed: The Fediverse Enhancement Proposal Process](./feps/fep-a4ed.md). Further process is described in FEP-a4ed. +Alternatively to steps 3. to 6., you can run + +```bash +python scripts/new_proposal.py TITLE OF YOUR PROPOSAL +``` + +that should create a prefilled template for you. + ## Editors The list of FEP's is facilitated by Editors who are listed in the [EDITORS.md](EDITORS.md) file. Editors are neutral custodians of the FEP process, who merge PR's, create tracking issues, and start discussion threads for each FEP in the [SocialHub](https://socialhub.activitypub.rocks) developer community forum. @@ -31,6 +41,6 @@ Do you have ideas to improve the FEP Process? Post your suggestions to the issue ## License -CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication To the extent possible under law, the authors of this document have waived all copyright and related or neighboring rights to this work. diff --git a/scripts/create_readme.py b/scripts/create_readme.py index cc99245..a43e195 100644 --- a/scripts/create_readme.py +++ b/scripts/create_readme.py @@ -1,47 +1,4 @@ -from tools import FepFile, get_fep_ids - -fep_files = [FepFile(fep) for fep in get_fep_ids()] -fep_files = reversed(fep_files) -fep_files = sorted(fep_files, key=lambda x: x.parsed_frontmatter["dateReceived"]) - -result = [] - - -def build_url_link(url): - url_number = url.split("/")[-1] - return f"[#{url_number}]({url})" - - -for fep in fep_files: - link = f"[FEP-{fep.fep}: {fep.title}](./{fep.filename})" - parsed = fep.parsed_frontmatter - - if "discussionsTo" in parsed: - url = parsed["discussionsTo"] - urls = url.split(", ") - discussions = " ".join(build_url_link(url) for url in urls) - else: - discussions = "" - - if "dateFinalized" in parsed: - date_final = parsed["dateFinalized"] - elif "dateWithdrawn" in parsed: - date_final = parsed["dateWithdrawn"] - else: - date_final = "-" - result.append( - f"""| {link} | `{parsed["status"]}` | {discussions} | {parsed["dateReceived"]} | {date_final} |\n""" - ) - - -# | [FEP-a4ed: The Fediverse Enhancement Proposal Process](./fep/a4ed/fep-a4ed.md) | `FINAL` | [N/A](https://codeberg.org/fediverse/fep/issues) | 2020-10-16 | 2020-01-18 - +from tools import Readme with open("README.md", "w") as f1: - with open("scripts/frontmatter.md") as f: - f1.write(f.read().removesuffix("\n")) - - f1.writelines(result) - - with open("scripts/backmatter.md") as f: - f1.write(f.read()) + f1.writelines(Readme().content) diff --git a/scripts/frontmatter.md b/scripts/frontmatter.md index 2578f1b..9f2d897 100644 --- a/scripts/frontmatter.md +++ b/scripts/frontmatter.md @@ -14,4 +14,3 @@ The FEP Process is an initiative of the [SocialHub](https://socialhub.activitypu | Title | Status | Tracking issue | `dateReceived` | `dateFinalized` (or `dateWithdrawn`) | | --- | --- | ----- | ------- | ------ | - diff --git a/scripts/tools/__init__.py b/scripts/tools/__init__.py index ccb2dfd..e96edcc 100644 --- a/scripts/tools/__init__.py +++ b/scripts/tools/__init__.py @@ -1,6 +1,8 @@ import glob import hashlib +from .fep_file import FepFile + def title_to_slug(title): return hashlib.sha256(title.encode("utf-8")).hexdigest()[:4] @@ -11,70 +13,54 @@ def get_fep_ids(): yield fep.removeprefix("fep/") -class FepFile: - def __init__(self, fep): - self.fep = fep - with open(self.filename) as f: - self.frontmatter, self.content = FepFile.parsefile(f) +def build_url_link(url): + url_number = url.split("/")[-1] + return f"[#{url_number}]({url})" + + +class Readme: + @property + def content(self): + return self.frontmatter + self.table + self.backmatter @property - def filename(self): - return f"fep/{self.fep}/fep-{self.fep}.md" + def frontmatter(self): + with open("scripts/frontmatter.md") as f: + return f.readlines() @property - def summary(self): + def backmatter(self): + with open("scripts/backmatter.md") as f: + return f.readlines() + + @property + def table(self): + fep_files = [FepFile(fep) for fep in get_fep_ids()] + fep_files = reversed(fep_files) + fep_files = sorted( + fep_files, key=lambda x: x.parsed_frontmatter["dateReceived"] + ) + result = [] - is_summary = False - for x in self.content: - if is_summary: - if x.startswith("##"): - return "\n".join(result) - result.append(x) - elif x == "## Summary": - is_summary = True - def write(self): - with open(self.filename, "w") as f: - f.write("---\n") - for x in self.frontmatter: - f.write(x + "\n") - f.write("---\n") - for x in self.content: - f.write(x + "\n") + for fep in fep_files: + link = f"[FEP-{fep.fep}: {fep.title}](./{fep.filename})" + parsed = fep.parsed_frontmatter - @property - def parsed_frontmatter(self): - split = [x.split(":", 1) for x in self.frontmatter] - return {a: b.strip() for a, b in split} + if "discussionsTo" in parsed: + url = parsed["discussionsTo"] + urls = url.split(", ") + discussions = " ".join(build_url_link(url) for url in urls) + else: + discussions = "" - @property - def title(self): - titles = [x for x in self.content if x.startswith("# ")] - assert len(titles) > 0 - - title = titles[0] - - begin_title = f"# FEP-{self.fep}: " - - assert title.startswith(begin_title) - true_title = title.removeprefix(begin_title) - - return true_title - - @staticmethod - def parsefile(f): - lines = f.readlines() - - status = 0 - frontmatter = [] - content = [] - - for line in lines: - if line == "---\n" and status <= 2: - status += 1 - elif status == 1: - frontmatter.append(line.removesuffix("\n")) - elif status >= 2: - content.append(line.removesuffix("\n")) - - return frontmatter, content + if "dateFinalized" in parsed: + date_final = parsed["dateFinalized"] + elif "dateWithdrawn" in parsed: + date_final = parsed["dateWithdrawn"] + else: + date_final = "-" + result.append( + f"""| {link} | `{parsed["status"]}` | {discussions} | {parsed["dateReceived"]} | {date_final} |\n""" + ) + return result diff --git a/scripts/tools/fep_file.py b/scripts/tools/fep_file.py new file mode 100644 index 0000000..30f227d --- /dev/null +++ b/scripts/tools/fep_file.py @@ -0,0 +1,67 @@ +class FepFile: + def __init__(self, fep): + self.fep = fep + with open(self.filename) as f: + self.frontmatter, self.content = FepFile.parsefile(f) + + @property + def filename(self): + return f"fep/{self.fep}/fep-{self.fep}.md" + + @property + def summary(self): + result = [] + is_summary = False + for x in self.content: + if is_summary: + if x.startswith("##"): + return "\n".join(result) + result.append(x) + elif x == "## Summary": + is_summary = True + + def write(self): + with open(self.filename, "w") as f: + f.write("---\n") + for x in self.frontmatter: + f.write(x + "\n") + f.write("---\n") + for x in self.content: + f.write(x + "\n") + + @property + def parsed_frontmatter(self): + split = [x.split(":", 1) for x in self.frontmatter] + return {a: b.strip() for a, b in split} + + @property + def title(self): + titles = [x for x in self.content if x.startswith("# ")] + assert len(titles) > 0 + + title = titles[0] + + begin_title = f"# FEP-{self.fep}: " + + assert title.startswith(begin_title) + true_title = title.removeprefix(begin_title) + + return true_title + + @staticmethod + def parsefile(f): + lines = f.readlines() + + status = 0 + frontmatter = [] + content = [] + + for line in lines: + if line == "---\n" and status <= 2: + status += 1 + elif status == 1: + frontmatter.append(line.removesuffix("\n")) + elif status >= 2: + content.append(line.removesuffix("\n")) + + return frontmatter, content diff --git a/scripts/tools/test_readme.py b/scripts/tools/test_readme.py new file mode 100644 index 0000000..0c79359 --- /dev/null +++ b/scripts/tools/test_readme.py @@ -0,0 +1,13 @@ +import pytest + +from scripts.tools import Readme + + +@pytest.mark.skip("Only is correct for main branch and not pull requests") +def test_readme(): + with open("README.md") as f: + lines = f.readlines() + + expected = Readme().content + + assert lines == expected