Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate from janky custom manifest format to yaml #96

Merged
merged 54 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
899a552
feat: migrate from janky custom manifest format to yaml
jooooscha Jan 20, 2024
c9e38ca
feat: migrate to yaml
jooooscha Jan 20, 2024
3b594aa
CI: Update plugins
jooooscha Jan 21, 2024
6d4cf14
CI: Update plugins
jooooscha Mar 7, 2024
d45188a
feat: migrate 'fetch' command to use the new yaml manifest
jooooscha Mar 7, 2024
44153b9
feat: 'regenerate' command
jooooscha Mar 7, 2024
2eb7f8f
feat: implement deprecated flag
jooooscha Mar 7, 2024
03c1f35
only a test
jooooscha Mar 7, 2024
7417a59
CI: Update plugins
jooooscha Mar 7, 2024
c0f107d
chore: update all install-nix-action calls to use v26
jooooscha Mar 11, 2024
6732121
feat: replace source_line with id property
jooooscha Mar 11, 2024
5f3e241
fix: GithubPlugin add repo
jooooscha Mar 11, 2024
899b3b9
CI: Update plugins
jooooscha Mar 11, 2024
5816ae2
fix: gitlab and sourcehut plugins add repo
jooooscha Mar 11, 2024
1f2ba60
feat: rename 'deprecated' to 'warning'
jooooscha Mar 11, 2024
f560d2a
feat: update readme
jooooscha Mar 11, 2024
a5fc02b
feat: write warning to plugins.md
jooooscha Mar 11, 2024
1c5e7cd
CI: Update plugins
jooooscha Mar 11, 2024
5d4581c
feat: replace more of old 'line' format with new 'id' format
jooooscha Mar 11, 2024
2b2123d
fix: replace more 'line' with 'id'
jooooscha Mar 11, 2024
d4a216c
CI: Update plugins
jooooscha Mar 11, 2024
8dd021c
chore: remove print
jooooscha Mar 11, 2024
15297ba
feat: write '' instead of None in plugins.md when no warning exists
jooooscha Mar 11, 2024
b1119e1
CI: Update plugins
jooooscha Mar 11, 2024
16f8249
Merge branch 'main' into manifest-yaml
jooooscha Mar 27, 2024
0fd082a
CI: Update plugins
jooooscha Mar 27, 2024
aac3189
fix: use '/' in plugin id instead of '-'
jooooscha Mar 27, 2024
2b5d3f3
fix: plugins.json
jooooscha Mar 27, 2024
ad34bdc
CI: Update plugins
jooooscha Mar 27, 2024
ae80e6c
chore: remove old code
jooooscha Mar 27, 2024
f07392b
fix: update manifest.yaml
jooooscha Mar 27, 2024
b9511b6
CI: Update plugins
jooooscha Mar 27, 2024
1dcefa4
CI: Update plugins
jooooscha Mar 27, 2024
8e2611d
feat: improve code readability by adding types and restructuring code…
jooooscha Mar 29, 2024
03d44ce
feat: improve error readability of Github api limits
jooooscha Mar 29, 2024
ac1886d
CI: Update plugins
jooooscha Mar 29, 2024
7126252
fix: data not read correctly from .plugin.json when github api limit hit
jooooscha Mar 29, 2024
870b9f3
chore: code cleanup
jooooscha Mar 29, 2024
5a4e9ea
fix: handle old .plugins.json entries (should only be needed for one …
jooooscha Mar 29, 2024
6479bee
CI: Update plugins
jooooscha Mar 29, 2024
df08338
fix: fix some old entries
jooooscha Mar 29, 2024
199b672
CI: Update plugins
jooooscha Mar 29, 2024
21d436c
fix: some more old .plugins.json entries
jooooscha Mar 29, 2024
b1db2a4
fix: try to handle error better during writing the nix file
jooooscha Mar 29, 2024
12718c9
fix: json file
jooooscha Mar 29, 2024
576ad22
fix: remove test entry in manifest.yaml
jooooscha Mar 29, 2024
5f43f57
CI: Update plugins
jooooscha Mar 29, 2024
245bb0a
feat: use warning from manifest, even when loading plugin from .plugi…
jooooscha Mar 29, 2024
5e46e65
feat: add --only <owner>/<repo> option. Use it to update a specific p…
jooooscha Mar 30, 2024
3820148
chore: update gitsigns manually, to remove test warning
jooooscha Mar 30, 2024
5ca3d28
feat: transfere missing plugin 'leetcode' from old manifest
jooooscha Mar 30, 2024
12bd7e3
Merge branch 'main' into manifest-yaml
jooooscha Mar 30, 2024
543e992
fix: plugins.json
jooooscha Mar 30, 2024
51e303c
CI: Update plugins
jooooscha Mar 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,938 changes: 968 additions & 970 deletions .plugins.json

Large diffs are not rendered by default.

20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,19 @@ More info on using neovim with nix can be found here: [NixOS Neovim](https://nix

### How to add a new plugin

#### 1. Add the plugin to manifest.txt:
#### 1. Add the plugin to manifest.yaml:

The new yaml format has the following format

```
# Examples

haringsrob/nvim_context_vt
sourcehut:henriquehbr/ataraxis.lua
gitlab:yorickpeterse/nvim-pqf
williamboman/mason.nvim:45b9a4da776d9fb017960b3ac7241161fb7bc578
foo/bar::baz --> renamed to baz
foo/bar:dev --> using dev branch
- owner: nvim-telescope
repo: telescope.nvim
# the following keys are optional
branch: ... # explicitly select branch
custom_name: ... # set custom name, used to fix name clashes
license: ... # specify license
commit: ... # specify commit to use, can be used when newest version is broken
warning: ... # add a waning that will be displayed when using the plugin, will also be visible in plugins.md
```

Supported are Github (default), SourceHut, and GitLab.
Expand Down
1 change: 1 addition & 0 deletions bin/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ requests = "^2.28.2"
cleo = "^2.0.1"
jsonpickle = "*"
dateparser = "1.1.8"
PyYAML = "^6.0"

[tool.poetry.group.test.dependencies]
pytest-cov = "^4.0.0"
Expand Down
2 changes: 2 additions & 0 deletions bin/update_vim_plugins/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
from .update import UpdateCommand
from .cleanup import CleanUpCommand
from .fetch import FetchCommand
from .regenerate import RegenerateCommand


def main():
application = Application()
application.add(UpdateCommand())
application.add(CleanUpCommand())
application.add(FetchCommand())
application.add(RegenerateCommand())
application.run()


Expand Down
5 changes: 3 additions & 2 deletions bin/update_vim_plugins/cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ def handle(self):
"""Main command function"""

# all cleaning up will be done during reading and writing automatically
manifest = read_manifest_to_spec()
# manifest = read_manifest_to_spec()
manifest = read_manifest_yaml_to_spec()
blacklist = read_blacklist_to_spec()

new_manifest = [ spec for spec in manifest if spec not in blacklist ]

new_manifest_filterd = self.filter_renamed(new_manifest)

write_manifest_from_spec(new_manifest_filterd)
write_manifest_yaml_from_spec(new_manifest_filterd)

self.line("<comment>Done</comment>")

Expand Down
12 changes: 7 additions & 5 deletions bin/update_vim_plugins/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,27 @@ class FetchCommand(Command):
def handle(self):
"""Main command function"""

specs = read_manifest()
specs = read_manifest_yaml_to_spec()
specs += self.fetch_awesome()
specs += self.fetch_m15a()

write_manifest(specs)
write_manifest_yaml_from_spec(specs)

self.line("<comment>Done</comment>")

def fetch_m15a(self) -> list[str]:
def fetch_m15a(self) -> list[PluginSpec]:
self.line(f"<info>Fetching from m15a's repo</info>")

manifest = urlopen(M15A_MANIFEST).read()
manifest = str(manifest, 'utf-8')
manifest = manifest.split("\n")

specs = list(filter(lambda x: x != "", manifest))
specs = [ p for p in specs ]
specs = [ PluginSpec.from_spec(p) for p in specs ]

return specs

def fetch_awesome(self) -> list[str]:
def fetch_awesome(self) -> list[PluginSpec]:
self.line(f"<info>Fetching from awesome-neovim</info>")

readme = urlopen(AWESOME_NEOVIM_README).read()
Expand Down Expand Up @@ -108,6 +108,8 @@ def fetch_awesome(self) -> list[str]:

specs.append(spec)

specs = [ PluginSpec.from_spec(s) for s in specs ]

return specs


62 changes: 44 additions & 18 deletions bin/update_vim_plugins/helpers.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
from .spec import PluginSpec
import yaml
from pprint import pprint
import subprocess

MANIFEST_FILE = "./manifest.txt"
from .plugin import VimPlugin

# MANIFEST_FILE = "./manifest.txt"
MANIFEST_YAML = "./manifest.yaml"
BLACKLIST_FILE = "./blacklist.txt"
PKGS_FILE = "./pkgs/vim-plugins.nix"
AWESOME_NEOVIM_README = "https://raw.githubusercontent.com/rockerBOO/awesome-neovim/main/README.md"
M15A_MANIFEST = "https://raw.githubusercontent.com/m15a/nixpkgs-vim-extra-plugins/main/manifest.txt"
JSON_FILE = "./.plugins.json"
PLUGINS_LIST_FILE = "./plugins.md"

def read_manifest() -> list[str]:
with open(MANIFEST_FILE, "r") as file:
specs = set([ spec.strip() for spec in file.readlines() ])
# def read_manifest_to_spec() -> list[PluginSpec]:
# manifest = read_manifest()
# specs = [ PluginSpec.from_spec(spec.strip()) for spec in manifest ]

return sorted(specs)
# return sorted(specs)

def read_manifest_to_spec() -> list[PluginSpec]:
manifest = read_manifest()
specs = [ PluginSpec.from_spec(spec.strip()) for spec in manifest ]
def read_manifest_yaml_to_spec() -> list[PluginSpec]:
with open(MANIFEST_YAML, "r") as file:
data = yaml.safe_load(file)

specs = [ PluginSpec.from_yaml(p) for p in data ]

return sorted(specs)


def read_blacklist() -> list[str]:
with open(BLACKLIST_FILE, "r") as file:
blacklisted_specs = set([ spec.strip() for spec in file.readlines() ])
Expand All @@ -32,19 +41,36 @@ def read_blacklist_to_spec() -> list[PluginSpec]:

return sorted(specs)

def write_manifest(specs: list[str]|set[str]):
"""write specs to manifest file. Does some cleaning up"""
def write_plugins_nix(plugins: list[VimPlugin]):
plugins.sort()

header = "{ lib, buildVimPlugin, fetchurl, fetchgit }: {"
footer = "}"

with open(MANIFEST_FILE, "w") as file:
with open(PKGS_FILE, "w") as file:
file.write(header)
for plugin in plugins:
try:
file.write(f"{plugin.to_nix()}\n")
except Exception as e:
pass

specs = sorted(set(specs), key=lambda x: x.lower())
specs = [ p for p in specs ]
file.write(footer)

for s in specs:
file.write(f"{s}\n")
def format_nix_output():
subprocess.run(
["alejandra", PKGS_FILE],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)

def write_manifest_from_spec(specs: list[PluginSpec]):

def write_manifest_yaml_from_spec(specs: list[PluginSpec]):
"""write specs to manifest file. Does some cleaning up"""

strings = [ f"{spec}" for spec in specs ]
write_manifest(strings)
strings = [ p.to_dict() for p in specs ]
y = yaml.dump(strings, default_flow_style=False, sort_keys=False)
with open(MANIFEST_YAML, "w") as file:
file.write(y)
file.write("\n")

45 changes: 36 additions & 9 deletions bin/update_vim_plugins/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,47 @@ class VimPlugin:
description: str = "No description"
homepage: str
license: License
source_line: str
checked: date = datetime.now().date()
warning: str | None = None

@property
def id(self) -> str:
if not hasattr(self, 'repo'): # WARN: should be removed after a few runs, only needed to handle old .plugin.json entries
self.repo = self.source_line.split("/")[1]

return f"{self.owner}/{self.repo}"

def to_nix(self):
"""Return the nix expression for this plugin."""
meta = f'with lib; {{ description = "{self.description}"; homepage = "{self.homepage}"; license = with licenses; [ {self.license.value} ]; }}'
return f'/* Generated from: {self.source_line} */ {self.name} = buildVimPlugin {{ pname = "{self.name}"; version = "{self.version}"; src = {self.source.get_nix_expression()}; meta = {meta}; }};'

if self.warning:
warning = f"lib.warn \"Warning for '{self.name}': {self.warning}\""
else:
warning = ""

return f'''
/* Generated from: {self.id} */
{self.name} = {warning} buildVimPlugin {{
pname = "{self.name}";
version = "{self.version}";
src = {self.source.get_nix_expression()};
meta = {meta};
}};
'''

def to_json(self):
"""Serizalize the plugin to json"""
return jsonpickle.encode(self)

def to_markdown(self):
link = f"[{self.source_line}]({self.homepage})"
link = f"[{self.id}]({self.homepage})"
version = f"{self.version}"
package_name = f"{self.name}"

return f"| {link} | {version} | `{package_name}` |"
warning = f"{self.warning or ''}"

return f"| {link} | {version} | `{package_name}` | {warning}"

def __lt__(self, o: object) -> bool:
if not isinstance(o, VimPlugin):
Expand All @@ -67,21 +90,24 @@ class GitHubPlugin(VimPlugin):
def __init__(self, plugin_spec: PluginSpec) -> None:
"""Initialize a GitHubPlugin."""

full_name = f"{plugin_spec.owner}/{plugin_spec.repo}"
owner = plugin_spec.owner
repo = plugin_spec.repo
full_name = f"{owner}/{repo}"
repo_info = self._api_call(f"repos/{full_name}")
default_branch = plugin_spec.branch or repo_info["default_branch"]
api_callback = self._api_call(f"repos/{full_name}/commits/{default_branch}")
latest_commit = api_callback["commit"]
sha = api_callback["sha"]

self.name = plugin_spec.name
self.owner = plugin_spec.owner
self.repo = repo
self.owner = owner
self.version = parse(latest_commit["committer"]["date"]).date()
self.source = UrlSource(f"https://github.com/{full_name}/archive/{sha}.tar.gz")
self.description = (repo_info.get("description") or "").replace('"', '\\"')
self.homepage = repo_info["html_url"]
self.license = plugin_spec.license or License.from_spdx_id((repo_info.get("license") or {}).get("spdx_id"))
self.source_line = plugin_spec.line
self.warning = plugin_spec.warning

def _api_call(self, path: str, token: str | None = _get_github_token()):
"""Call the GitHub API."""
Expand All @@ -107,13 +133,14 @@ def __init__(self, plugin_spec: PluginSpec) -> None:
sha = latest_commit["id"]

self.name = plugin_spec.name
self.repo = plugin_spec.repo
self.owner = plugin_spec.owner
self.version = parse(latest_commit["created_at"]).date()
self.source = UrlSource(f"https://gitlab.com/api/v4/projects/{full_name}/repository/archive.tar.gz?sha={sha}")
self.description = (repo_info.get("description") or "").replace('"', '\\"')
self.homepage = repo_info["web_url"]
self.license = plugin_spec.license or License.from_spdx_id(repo_info.get("license", {}).get("key"))
self.source_line = plugin_spec.line
self.warning = plugin_spec.warning

def _api_call(self, path: str) -> dict:
"""Call the Gitlab API."""
Expand Down Expand Up @@ -144,13 +171,13 @@ def __init__(self, plugin_spec: PluginSpec) -> None:
sha = latest_commit["id"]

self.name = plugin_spec.name
self.repo = plugin_spec.repo
self.owner = plugin_spec.owner
self.version = parse(latest_commit["timestamp"]).date()
self.description = (repo_info.get("description") or "").replace('"', '\\"')
self.homepage = f"https://git.sr.ht/~{plugin_spec.owner}/{plugin_spec.repo}"
self.source = GitSource(self.homepage, sha)
self.license = plugin_spec.license or License.UNKNOWN # cannot be determined via API
self.source_line = plugin_spec.line

def _api_call(self, path: str, token: str | None = _get_sourcehut_token()):
"""Call the SourceHut API."""
Expand Down
31 changes: 31 additions & 0 deletions bin/update_vim_plugins/regenerate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from cleo.commands.command import Command
from cleo.helpers import argument
import json
import jsonpickle
from pprint import pprint

from .helpers import *

class RegenerateCommand(Command):
name = "regenerate"
description = "Regenerate plugins from .plugins.json"

def handle(self):
"""Main command function"""


json_data = None
with open(JSON_FILE, "r+") as json_file:
json_data = json.load(json_file)

plugins = [ jsonpickle.decode(plugin_json) for plugin_json in json_data.values() ]

self.line(f"<info>Generating nix output</info>")

write_plugins_nix(plugins)

self.line(f"<info>Formatting nix output</info>")

format_nix_output()

self.line("<comment>Done</comment>")
Loading