aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/up/update-vim-plugins/update_vim_plugins
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/up/update-vim-plugins/update_vim_plugins')
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py0
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py15
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py100
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py61
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py121
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py182
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py143
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py0
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py44
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py32
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py144
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py136
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py212
13 files changed, 0 insertions, 1190 deletions
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py
+++ /dev/null
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py
deleted file mode 100644
index a8d9e06f..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from cleo.application import Application
-
-from .update import UpdateCommand
-from .cleanup import CleanUpCommand
-
-
-def main():
- application = Application()
- application.add(UpdateCommand())
- application.add(CleanUpCommand())
- application.run()
-
-
-if __name__ == "__main__":
- main()
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py
deleted file mode 100644
index fd313ed0..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from cleo.commands.command import Command
-from cleo.helpers import argument
-
-from .helpers import read_manifest_to_spec, read_blacklist_to_spec, write_manifest_from_spec
-
-
-class CleanUpCommand(Command):
- name = "cleanup"
- description = "Clean up manifest"
- arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)]
-
- def handle(self):
- """Main command function"""
-
- plug_dir = self.argument("plug_dir")
- self.line("<comment>Checking manifest file</comment>")
- # all cleaning up will be done during reading and writing automatically
- manifest = read_manifest_to_spec(plug_dir)
- blacklist = read_blacklist_to_spec(plug_dir)
-
- 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, plug_dir)
-
- self.line("<comment>Done</comment>")
-
- def filter_renamed(self, specs):
- """Filter specs that define the same plugin (same owner and same repo) but with different properties.
- This could be a different name, source, or branch
- """
-
- error = False
- for i, p in enumerate(specs):
- for p2 in specs:
- same_owner = p.owner.lower() == p2.owner.lower()
- same_repo = p.repo.lower() == p2.repo.lower()
- different_specs = p != p2
- marked_duplicate = p.marked_duplicate or p2.marked_duplicate
-
- if same_owner and same_repo and different_specs and not marked_duplicate:
- self.line("<info>The following lines appear to define the same plugin</info>")
-
- p_props_defined = p.branch is not None or p.custom_name is not None
- p2_props_defined = p2.branch is not None or p2.custom_name is not None
- p_is_lower_case = p.owner == p.owner.lower() and p.name == p.name.lower()
- p2_is_lower_case = p2.owner == p2.owner.lower() and p2.name == p2.name.lower()
-
- # list of conditions for selecting p
- select_p = p_props_defined and not p2_props_defined or p2_is_lower_case and not p_is_lower_case
- # list of conditions for selecting p2
- select_p2 = p2_props_defined and not p_props_defined or p_is_lower_case and not p2_is_lower_case
-
- # one is more defined and is all lower, but the other is not all lower
- # (we assume the not all lower case is the correct naming)
- error_props_lower = (
- p_props_defined and p_is_lower_case and not p2_props_defined and not p2_is_lower_case
- )
- error_props_lower2 = (
- p2_props_defined and p2_is_lower_case and not p_props_defined and not p_is_lower_case
- )
-
- # both props are defined
- error_props = p_props_defined and p2_props_defined
-
- # the sources are different
- error_source = p.repository_host != p2.repository_host
-
- if error_props_lower or error_props_lower2 or error_props or error_source:
- self.line(" • <error>Cannot determine which is the correct plugin</error>")
- self.line(f" - {p.line}")
- self.line(f" - {p2.line}")
- error = True
- # remove second spec to not encounter the error twice
- # this will not be written to the manifest.txt because we set
- # the error flag and will exit after the loop
- specs.remove(p2)
- elif select_p:
- self.line(f" - <comment>{p.line}</comment>")
- self.line(f" - {p2.line}")
- specs.remove(p2)
- elif select_p2:
- self.line(f" - {p.line}")
- self.line(f" - <comment>{p2.line}</comment>")
- specs.remove(p)
- else:
- self.line(" • <error>Logic error in correct spec determination</error>")
- self.line(f" - {p.line}")
- self.line(f" - {p2.line}")
- error = True
- # remove second spec to not encounter the error twice
- # this will not be written to the manifest.txt because we set
- # the error flag and will exit after the loop
- specs.remove(p)
- if error:
- # exit after all errors have been found
- exit(1)
-
- return specs
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py
deleted file mode 100644
index 8a28b0e8..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from .spec import PluginSpec
-
-MANIFEST_FILE = "manifest.txt"
-BLACKLIST_FILE = "blacklist.txt"
-PKGS_FILE = "default.nix"
-JSON_FILE = ".plugins.json"
-PLUGINS_LIST_FILE = "plugins.md"
-
-
-def get_const(const: str, plug_dir: str) -> str:
- out = plug_dir + "/" + const
- return out
-
-
-def read_manifest(plug_dir: str) -> list[str]:
- with open(get_const(MANIFEST_FILE, plug_dir), "r") as file:
- specs = set([spec.strip() for spec in file.readlines()])
-
- return sorted(specs)
-
-
-def read_manifest_to_spec(plug_dir: str) -> list[PluginSpec]:
- manifest = read_manifest(plug_dir)
- specs = [PluginSpec.from_spec(spec.strip()) for spec in manifest]
-
- return sorted(specs)
-
-
-def read_blacklist(plug_dir: str) -> list[str]:
- with open(get_const(BLACKLIST_FILE, plug_dir), "r") as file:
- if len(file.readlines()) == 0:
- return [""]
- else:
- blacklisted_specs = set([spec.strip() for spec in file.readlines()])
-
- return sorted(blacklisted_specs)
-
-
-def read_blacklist_to_spec(plug_dir: str) -> list[PluginSpec]:
- blacklist = read_blacklist(plug_dir)
- specs = [PluginSpec.from_spec(spec.strip()) for spec in blacklist]
-
- return sorted(specs)
-
-
-def write_manifest(specs: list[str] | set[str], plug_dir: str):
- """write specs to manifest file. Does some cleaning up"""
-
- with open(get_const(MANIFEST_FILE, plug_dir), "w") as file:
- specs = sorted(set(specs), key=lambda x: x.lower())
- specs = [p for p in specs]
-
- for s in specs:
- file.write(f"{s}\n")
-
-
-def write_manifest_from_spec(specs: list[PluginSpec], plug_dir: str):
- """write specs to manifest file. Does some cleaning up"""
-
- strings = [f"{spec}" for spec in specs]
- write_manifest(strings, plug_dir)
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py
deleted file mode 100644
index 66a8df4c..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py
+++ /dev/null
@@ -1,121 +0,0 @@
-import abc
-import enum
-import json
-import subprocess
-
-
-def nix_prefetch_url(url):
- """Return the sha256 hash of the given url."""
- subprocess_output = subprocess.check_output(
- ["nix-prefetch-url", "--type", "sha256", url],
- stderr=subprocess.DEVNULL,
- )
- sha256 = subprocess_output.decode("utf-8").strip()
- return sha256
-
-
-def nix_prefetch_git(url):
- """Return the sha256 hash of the given git url."""
- subprocess_output = subprocess.check_output(["nix-prefetch-git", url], stderr=subprocess.DEVNULL)
- sha256 = json.loads(subprocess_output)["sha256"]
- return sha256
-
-
-class Source(abc.ABC):
- """Abstract base class for sources."""
-
- url: str
- sha256: str
-
- @abc.abstractmethod
- def __init__(self, url: str) -> None:
- """Initialize a Source."""
-
- @abc.abstractmethod
- def get_nix_expression(self):
- """Return the nix expression for this source."""
-
- def __repr__(self):
- """Return the representation of this source."""
- return self.get_nix_expression()
-
-
-class UrlSource(Source):
- """A source that is a url."""
-
- def __init__(self, url: str) -> None:
- """Initialize a UrlSource."""
- self.url = url
- self.sha256 = nix_prefetch_url(url)
-
- def get_nix_expression(self):
- """Return the nix expression for this source."""
- return f'fetchurl {{ url = "{self.url}"; sha256 = "{self.sha256}"; }}'
-
-
-class GitSource(Source):
- """A source that is a git repository."""
-
- def __init__(self, url: str, rev: str) -> None:
- """Initialize a GitSource."""
- self.url = url
- self.rev = rev
- self.sha256 = nix_prefetch_git(url)
-
- def get_nix_expression(self):
- """Return the nix expression for this source."""
- return f'fetchgit {{ url = "{self.url}"; rev = "{self.rev}"; sha256 = "{self.sha256}"; }}'
-
-
-class License(enum.Enum):
- """An enumeration of licenses."""
-
- AGPL_3_0 = "agpl3Only"
- APACHE_2_0 = "asf20"
- BSD_2_CLAUSE = "bsd2"
- BSD_3_CLAUSE = "bsd3"
- BSL_1_0 = "bsl1_0"
- CC0_1_0 = "cc0"
- EPL_2_0 = "epl20"
- GPL_2_0 = "gpl2Only"
- GPL_3_0 = "gpl3Only"
- ISCLGPL_2_1 = "lgpl21Only"
- MIT = "mit"
- MPL_2_0 = "mpl20"
- UNLUNLICENSE = "unlicense"
- WTFPL = "wtfpl"
- UNFREE = "unfree"
- UNKNOWN = ""
-
- @classmethod
- def from_spdx_id(cls, spdx_id: str | None) -> "License":
- """Return the License from the given spdx_id."""
- mapping = {
- "AGPL-3.0": cls.AGPL_3_0,
- "AGPL-3.0-only": cls.AGPL_3_0,
- "Apache-2.0": cls.APACHE_2_0,
- "BSD-2-Clause": cls.BSD_2_CLAUSE,
- "BSD-3-Clause": cls.BSD_3_CLAUSE,
- "BSL-1.0": cls.BSL_1_0,
- "CC0-1.0": cls.CC0_1_0,
- "EPL-2.0": cls.EPL_2_0,
- "GPL-2.0": cls.GPL_2_0,
- "GPL-2.0-only": cls.GPL_2_0,
- "GPL-3.0": cls.GPL_3_0,
- "GPL-3.0-only": cls.GPL_3_0,
- "LGPL-2.1-only": cls.ISCLGPL_2_1,
- "MIT": cls.MIT,
- "MPL-2.0": cls.MPL_2_0,
- "Unlicense": cls.UNLUNLICENSE,
- "WTFPL": cls.WTFPL,
- }
-
- if spdx_id is None:
- return cls.UNKNOWN
-
- spdx_id = spdx_id.upper()
- return mapping.get(spdx_id, cls.UNKNOWN)
-
- def __str__(self):
- """Return the string representation of this license."""
- return self.value
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py
deleted file mode 100644
index 8334ad53..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py
+++ /dev/null
@@ -1,182 +0,0 @@
-import logging
-import os
-import urllib
-
-import requests
-import jsonpickle
-from datetime import datetime, date
-from dateparser import parse
-
-from .nix import GitSource, License, Source, UrlSource
-from .spec import PluginSpec, RepositoryHost
-
-
-logger = logging.getLogger(__name__)
-
-
-class VimPlugin:
- """Abstract base class for vim plugins."""
-
- name: str
- owner: str
- repo: str
- version: date
- source: Source
- description: str = "No description"
- homepage: str
- license: License
- source_line: str
- checked: date = datetime.now().date()
-
- 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}; }};'
-
- def to_json(self):
- """Serizalize the plugin to json"""
- return jsonpickle.encode(self)
-
- def to_markdown(self):
- link = f"[{self.source_line}]({self.homepage})"
- version = f"{self.version}"
- package_name = f"{self.name}"
- checked = f"{self.checked}"
-
- return f"| {link} | {version} | `{package_name}` | {checked} |"
-
- def __lt__(self, o: object) -> bool:
- if not isinstance(o, VimPlugin):
- return False
-
- return self.name.lower() < o.name.lower()
-
- def __repr__(self):
- """Return the representation of this plugin."""
- return f"VimPlugin({self.name!r}, {self.version.strftime('%Y-%m-%d')})"
-
-
-def _get_github_token():
- token = os.environ.get("GITHUB_TOKEN")
- if token is None:
- # NOTE: This should never use more than the free api requests <2023-12-09>
- pass
- # logger.warning("GITHUB_TOKEN environment variable not set")
- return token
-
-
-class GitHubPlugin(VimPlugin):
- def __init__(self, plugin_spec: PluginSpec) -> None:
- """Initialize a GitHubPlugin."""
-
- full_name = f"{plugin_spec.owner}/{plugin_spec.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.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
-
- def _api_call(self, path: str, token: str | None = _get_github_token()):
- """Call the GitHub API."""
- url = f"https://api.github.com/{path}"
- headers = {"Content-Type": "application/json"}
- if token is not None:
- headers["Authorization"] = f"token {token}"
- response = requests.get(url, headers=headers)
- if response.status_code != 200:
- raise RuntimeError(f"GitHub API call failed: {response.text}")
- return response.json()
-
-
-class GitlabPlugin(VimPlugin):
- def __init__(self, plugin_spec: PluginSpec) -> None:
- """Initialize a GitlabPlugin."""
-
- full_name = urllib.parse.quote(f"{plugin_spec.owner}/{plugin_spec.repo}", safe="")
- repo_info = self._api_call(f"projects/{full_name}")
- default_branch = plugin_spec.branch or repo_info["default_branch"]
- api_callback = self._api_call(f"projects/{full_name}/repository/branches/{default_branch}")
- latest_commit = api_callback["commit"]
- sha = latest_commit["id"]
-
- self.name = plugin_spec.name
- 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
-
- def _api_call(self, path: str) -> dict:
- """Call the Gitlab API."""
- url = f"https://gitlab.com/api/v4/{path}"
- response = requests.get(url)
- if response.status_code != 200:
- raise RuntimeError(f"Gitlab API call failed: {response.text}")
- return response.json()
-
-
-def _get_sourcehut_token():
- token = os.environ.get("SOURCEHUT_TOKEN")
- if token is None:
- # NOTE: This should never use more than the free requests <2023-12-09>
- pass
- # logger.warning("SOURCEHUT_TOKEN environment variable not set")
- return token
-
-
-class SourceHutPlugin(VimPlugin):
- def __init__(self, plugin_spec: PluginSpec) -> None:
- """Initialize a SourceHutPlugin."""
-
- repo_info = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}")
- if plugin_spec.branch is None:
- commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log")
- else:
- commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log/{plugin_spec.branch}")
- latest_commit = commits["results"][0]
- sha = latest_commit["id"]
-
- self.name = plugin_spec.name
- 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."""
-
- url = f"https://git.sr.ht/api/{path}"
- headers = {"Content-Type": "application/json"}
- if token is not None:
- headers["Authorization"] = f"token {token}"
- response = requests.get(url, headers=headers)
- if response.status_code != 200:
- raise RuntimeError(f"SourceHut API call failed: {response.json()}")
- return response.json()
-
-
-def plugin_from_spec(plugin_spec: PluginSpec) -> VimPlugin:
- """Initialize a VimPlugin."""
-
- if plugin_spec.repository_host == RepositoryHost.GITHUB:
- return GitHubPlugin(plugin_spec)
- elif plugin_spec.repository_host == RepositoryHost.GITLAB:
- return GitlabPlugin(plugin_spec)
- elif plugin_spec.repository_host == RepositoryHost.SOURCEHUT:
- return SourceHutPlugin(plugin_spec)
- else:
- raise NotImplementedError(f"Unsupported source: {plugin_spec.repository_host}")
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py
deleted file mode 100644
index 0f2fb29c..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import enum
-import re
-
-from .nix import License
-
-
-class RepositoryHost(enum.Enum):
- """A repository host."""
-
- GITHUB = "github"
- GITLAB = "gitlab"
- SOURCEHUT = "sourcehut"
-
-
-class PluginSpec:
- """A Vim plugin Spec."""
-
- @classmethod
- def from_spec(cls, spec):
- """The spec line must be in the format:
- [<repository_host>:]<owner>/<repo>[:<branch>][:name].
-
- repository_host is one of github (default), gitlab, or sourcehut.
- owner is the repository owner.
- repo is the repository name.
- branch is the git branch.
- name is the name to use for the plugin (default is value of repo).
- """
- repository_host = RepositoryHost.GITHUB
- # gitref = "master"
-
- repository_host_regex = r"((?P<repository_host>[^:]+):)"
- owner_regex = r"(?P<owner>[^/:]+)"
- repo_regex = r"(?P<repo>[^:]+)"
- branch_regex = r"(:(?P<branch>[^:]+)?)"
- name_regex = r"(:(?P<name>[^:]+)?)"
- license_regex = r"(:(?P<license>[^:]+)?)"
- marked_duplicate_regex = r"(:(?P<duplicate>duplicate))"
-
- spec_regex = re.compile(
- f"^{repository_host_regex}?{owner_regex}/{repo_regex}{branch_regex}?{name_regex}?{license_regex}?{marked_duplicate_regex}?$",
- )
-
- match = spec_regex.match(spec)
- if match is None:
- raise ValueError(f"Invalid spec: {spec}")
-
- group_dict = match.groupdict()
-
- repository_host = RepositoryHost(group_dict.get("repository_host") or "github")
-
- owner = group_dict.get("owner")
- if owner is None:
- raise RuntimeError("Could not get owner")
-
- repo = group_dict.get("repo")
- if repo is None:
- raise RuntimeError("Could not get repo")
-
- branch = group_dict.get("branch")
- name = group_dict.get("name")
- license = group_dict.get("license")
- marked_duplicate = bool(group_dict.get("duplicate")) # True if 'duplicate', False if None
-
- line = spec
-
- return cls(repository_host, owner, repo, line, branch, name, license, marked_duplicate)
-
- def __init__(
- self,
- repository_host: RepositoryHost,
- owner: str,
- repo: str,
- line: str,
- branch: str | None = None,
- name: str | None = None,
- license: str | None = None,
- marked_duplicate: bool = False,
- ) -> None:
- """Initialize a VimPluginSpec."""
- self.repository_host = repository_host
- self.owner = owner
- self.repo = repo
- self.branch = branch
- self.custom_name = name
- self.name = name or repo.replace(".", "-").replace("_", "-")
- self.license = License(license) if license else None
- self.line = line
- self.marked_duplicate = marked_duplicate
-
- def __str__(self) -> str:
- """Return a string representation of a VimPluginSpec."""
- spec = ""
-
- if self.repository_host != RepositoryHost.GITHUB:
- spec += f"{self.repository_host.value}:"
-
- spec += f"{self.owner}/{self.repo}"
-
- spec += ":"
- if self.branch is not None:
- spec += self.branch
-
- spec += ":"
- if self.custom_name is not None:
- spec += self.custom_name
-
- spec += ":"
- if self.license is not None:
- spec += str(self.license)
-
- spec += ":"
- if self.marked_duplicate:
- spec += "duplicate"
-
- return spec.rstrip(":")
-
- def __repr__(self):
- """Return the representation of the specs"""
- return f"PluginSpec({self.owner}/{self.repo}, {self.name})"
-
- def to_spec(self):
- """Return a spec line for a VimPluginSpec."""
- return str(self)
-
- def __lt__(self, o: object) -> bool:
- if not isinstance(o, PluginSpec):
- return False
-
- return self.name.lower() < o.name.lower()
-
- def __eq__(self, o: object) -> bool:
- """Return True if the two specs are equal."""
- if not isinstance(o, PluginSpec):
- return False
-
- return (
- self.repository_host == o.repository_host
- and self.owner == o.owner
- and self.repo == o.repo
- and self.branch == o.branch
- and self.name == o.name
- )
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py
+++ /dev/null
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py
deleted file mode 100644
index 75dd251a..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import json
-
-import pytest
-from pytest_mock import MockerFixture
-
-from update_vim_plugins.nix import GitSource, UrlSource
-
-
-@pytest.fixture()
-def url():
- return "https://example.com"
-
-
-@pytest.fixture()
-def rev():
- return "1234567890abcdef"
-
-
-@pytest.fixture()
-def sha256():
- return "sha256-1234567890abcdef"
-
-
-@pytest.fixture()
-def url_source(mocker: MockerFixture, url: str, sha256: str):
- mocker.patch("subprocess.check_output", return_value=bytes(sha256, "utf-8"))
- return UrlSource(url)
-
-
-@pytest.fixture()
-def git_source(mocker: MockerFixture, url: str, rev: str, sha256: str):
- return_value = {
- "url": url,
- "rev": rev,
- "date": "1970-01-01T00:00:00+00:00",
- "path": "",
- "sha256": sha256,
- "fetchLFS": False,
- "fetchSubmodules": False,
- "deepClone": False,
- "leaveDotGit": False,
- }
- mocker.patch("subprocess.check_output", return_value=json.dumps(return_value).encode("utf-8"))
- return GitSource(url, rev)
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py
deleted file mode 100644
index 46e59f76..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from update_vim_plugins.nix import GitSource, License, UrlSource
-
-
-def test_url_source(url_source: UrlSource, url: str, sha256: str):
- assert url_source.url == url
- assert url_source.sha256 == sha256
-
-
-def test_url_source_nix_expression(url_source: UrlSource, url: str, sha256: str):
- assert url_source.get_nix_expression() == f'fetchurl {{ url = "{url}"; sha256 = "{sha256}"; }}'
-
-
-def test_git_source(git_source: GitSource, url: str, rev: str, sha256: str):
- assert git_source.url == url
- assert git_source.sha256 == sha256
- assert git_source.rev == rev
-
-
-def test_git_source_nix_expression(git_source: GitSource, url: str, rev: str, sha256: str):
- assert git_source.get_nix_expression() == f'fetchgit {{ url = "{url}"; rev = "{rev}"; sha256 = "{sha256}"; }}'
-
-
-def test_license_github():
- github_license = "MIT"
- license = License.from_spdx_id(github_license)
- assert license == License.MIT
-
-
-def test_license_gitlab():
- gitlab_license = "mit"
- license = License.from_spdx_id(gitlab_license)
- assert license == License.MIT
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py
deleted file mode 100644
index 32377e24..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import json
-from typing import Callable
-
-import pytest
-from pytest_mock import MockFixture
-
-from update_vim_plugins.nix import License, UrlSource
-from update_vim_plugins.plugin import GitHubPlugin, VimPlugin
-from update_vim_plugins.spec import PluginSpec
-
-
-@pytest.fixture()
-def mock_source(sha256: str):
- class MockSource:
- def __init__(self, *args, **kwargs):
- pass
-
- def get_nix_expression(self):
- return "src"
-
- return MockSource()
-
-
-@pytest.fixture()
-def mock_plugin(mock_source):
- class MockVimPlugin(VimPlugin):
- def __init__(self):
- self.name = "test"
- self.version = "1.0.0"
- self.source = mock_source
- self.description = "No description"
- self.homepage = "https://example.com"
- self.license = License.UNKNOWN
-
- return MockVimPlugin()
-
-
-def test_vim_plugin_nix_expression(mock_plugin):
- assert (
- mock_plugin.get_nix_expression()
- == 'test = buildVimPluginFrom2Nix { pname = "test"; version = "1.0.0"; src = src; meta = with lib; { description = "No description"; homepage = "https://example.com"; license = with licenses; [ ]; }; };'
- )
-
-
-class MockResponse:
- def __init__(self, status_code: int, content: bytes):
- self.status_code = status_code
- self.content = content
-
- def json(self):
- return json.loads(self.content)
-
-
-def mock_request_get(repsonses: dict[str, MockResponse]):
- respones_not_found = MockResponse(404, b'{"message": "Not Found"}')
-
- def mock_get(url: str, *args, **kwargs):
- return repsonses.get(url, respones_not_found)
-
- return mock_get
-
-
-@pytest.fixture()
-def github_commits_response():
- return MockResponse(
- 200,
- json.dumps(
- {
- "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
- "commit": {
- "committer": {
- "date": "2011-04-14T16:00:49Z",
- },
- },
- }
- ),
- )
-
-
-@pytest.fixture()
-def github_get(github_commits_response: MockResponse):
- repos_response = MockResponse(
- 200,
- json.dumps(
- {
- "html_url": "https://github.com/octocat/Hello-World",
- "description": "This your first repo!",
- "fork": False,
- "default_branch": "master",
- "license": {
- "spdx_id": "MIT",
- },
- }
- ),
- )
- responses = {
- "https://api.github.com/repos/octocat/Hello-World": repos_response,
- "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response,
- }
- return mock_request_get(responses)
-
-
-@pytest.fixture()
-def github_get_no_license(github_commits_response: MockResponse):
- repos_response = MockResponse(
- 200,
- json.dumps(
- {
- "html_url": "https://github.com/octocat/Hello-World",
- "description": "This your first repo!",
- "fork": False,
- "default_branch": "master",
- }
- ),
- )
- responses = {
- "https://api.github.com/repos/octocat/Hello-World": repos_response,
- "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response,
- }
- return mock_request_get(responses)
-
-
-def test_github_plugin(mocker: MockFixture, github_get: Callable, url_source: UrlSource):
- mocker.patch("requests.get", github_get)
- url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source)
-
- spec = PluginSpec.from_spec("octocat/Hello-World")
- plugin = GitHubPlugin(spec)
-
- assert plugin.name == "Hello-World"
- assert plugin.version == "2011-04-14"
- assert plugin.description == "This your first repo!"
- assert plugin.homepage == "https://github.com/octocat/Hello-World"
- assert plugin.license == License.MIT
-
-
-def test_github_plugin_no_license(mocker: MockFixture, github_get_no_license: Callable, url_source: UrlSource):
- mocker.patch("requests.get", github_get_no_license)
- url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source)
-
- spec = PluginSpec.from_spec("octocat/Hello-World")
- plugin = GitHubPlugin(spec)
-
- assert plugin.license == License.UNKNOWN
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py
deleted file mode 100644
index 2b9a1d24..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import pytest
-
-from update_vim_plugins.spec import PluginSpec, RepositoryHost
-
-
-@pytest.fixture()
-def owner():
- return "owner"
-
-
-@pytest.fixture()
-def repo():
- return "repo.nvim"
-
-
-@pytest.fixture()
-def branch():
- return "main"
-
-
-@pytest.fixture()
-def name():
- return "repo-nvim"
-
-
-@pytest.fixture()
-def license():
- return "mit"
-
-
-def test_from_spec_simple(owner: str, repo: str):
- vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}")
-
- assert vim_plugin.owner == owner
- assert vim_plugin.repo == repo
-
-
-def test_from_spec_with_gitref(owner: str, repo: str, branch: str):
- vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}:{branch}")
-
- assert vim_plugin.branch == branch
-
-
-def test_from_spec_with_name(owner: str, repo: str, name: str):
- vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}::{name}")
-
- assert vim_plugin.name == name
-
-
-@pytest.mark.parametrize("host", RepositoryHost)
-def test_from_spec_with_repository_host(owner: str, repo: str, host: RepositoryHost):
- vim_plugin = PluginSpec.from_spec(f"{host.value}:{owner}/{repo}")
-
- assert vim_plugin.repository_host == host
-
-
-def test_from_spec_without_repository_host(owner: str, repo: str):
- vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}")
-
- assert vim_plugin.repository_host == RepositoryHost.GITHUB
-
-
-def test_from_spec_complex(owner: str, repo: str, branch: str, name: str):
- vim_plugin = PluginSpec.from_spec(f"gitlab:{owner}/{repo}:{branch}:{name}")
-
- assert vim_plugin.repository_host == RepositoryHost.GITLAB
- assert vim_plugin.owner == owner
- assert vim_plugin.repo == repo
- assert vim_plugin.branch == branch
- assert vim_plugin.name == name
-
-
-def test_from_spec_invalid_spec():
- with pytest.raises(ValueError):
- PluginSpec.from_spec("invalid_spec")
-
-
-def test_to_spec_simple(owner: str, repo: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-
- assert vim_plugin.to_spec() == f"{owner}/{repo}"
-
-
-def test_to_spec_with_branch(owner: str, repo: str, branch: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch=branch)
- assert vim_plugin.to_spec() == f"{owner}/{repo}:{branch}"
-
-
-def test_to_spec_with_name(owner: str, repo: str, name: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name)
-
- assert vim_plugin.to_spec() == f"{owner}/{repo}::{name}"
-
-
-@pytest.mark.parametrize("host", [RepositoryHost.GITLAB, RepositoryHost.SOURCEHUT])
-def test_to_spec_with_repository_host(host: RepositoryHost, owner: str, repo: str):
- vim_plugin = PluginSpec(host, owner, repo)
-
- assert vim_plugin.to_spec() == f"{host.value}:{owner}/{repo}"
-
-
-def test_to_spec_complex(owner: str, repo: str, branch: str, name: str, license: str):
- vim_plugin = PluginSpec(RepositoryHost.GITLAB, owner, repo, branch=branch, name=name, license=license)
-
- assert vim_plugin.to_spec() == f"gitlab:{owner}/{repo}:{branch}:{name}:{license}"
-
-
-def test_spec_equal(owner: str, repo: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
- vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-
- assert vim_plugin == vim_plugin2
-
-
-def test_spec_not_equal_different_branch(owner: str, repo: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
- vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch="main")
-
- assert vim_plugin != vim_plugin2
-
-
-def test_spec_not_equal_different_name(owner: str, repo: str):
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
- vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name="renamed")
-
- assert vim_plugin != vim_plugin2
-
-
-def test_spec_equal_same_normalized_name(owner: str):
- repo = "repo.nvim"
- name = "repo-nvim"
-
- vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
- vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name)
-
- assert vim_plugin == vim_plugin2
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py
deleted file mode 100644
index b338d81d..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py
+++ /dev/null
@@ -1,212 +0,0 @@
-import subprocess
-from random import shuffle
-from cleo.helpers import argument, option
-from cleo.commands.command import Command
-from concurrent.futures import ThreadPoolExecutor, as_completed
-
-from pprint import pprint
-
-from .plugin import plugin_from_spec
-
-from .helpers import read_manifest_to_spec, get_const
-from .helpers import JSON_FILE, PLUGINS_LIST_FILE, PKGS_FILE
-
-import json
-import jsonpickle
-
-jsonpickle.set_encoder_options("json", sort_keys=True)
-
-
-class UpdateCommand(Command):
- name = "update"
- description = "Generate nix module from input file"
- arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)]
- options = [
- option("all", "a", description="Update all plugins. Else only update new plugins", flag=True),
- option("dry-run", "d", description="Show which plugins would be updated", flag=True),
- ]
-
- def handle(self):
- """Main command function"""
-
- plug_dir = self.argument("plug_dir")
- self.specs = read_manifest_to_spec(plug_dir)
-
- if self.option("all"):
- # update all plugins
- spec_list = self.specs
- known_plugins = []
- else:
- # filter plugins we already know
- spec_list = self.specs
-
- with open(get_const(JSON_FILE, plug_dir), "r") as json_file:
- data = json.load(json_file)
-
- known_specs = list(filter(lambda x: x.line in data, spec_list))
- known_plugins = [jsonpickle.decode(data[x.line]) for x in known_specs]
-
- spec_list = list(filter(lambda x: x.line not in data, spec_list))
-
- if self.option("dry-run"):
- self.line("<comment>These plugins would be updated</comment>")
- pprint(spec_list)
- self.line(f"<info>Total:</info> {len(spec_list)}")
- exit(0)
-
- processed_plugins, failed_plugins, failed_but_known = self.process_manifest(spec_list, plug_dir)
-
- processed_plugins += known_plugins # add plugins from .plugins.json
- processed_plugins: list = sorted(set(processed_plugins)) # remove duplicates based only on source line
-
- self.check_duplicates(processed_plugins)
-
- if failed_plugins != []:
- self.line("<error>Not processed:</error> The following plugins could not be updated")
- for s, e in failed_plugins:
- self.line(f" - {s!r} - {e}")
-
- if failed_but_known != []:
- self.line(
- "<error>Not updated:</error> The following plugins could not be updated but an older version is known"
- )
- for s, e in failed_but_known:
- self.line(f" - {s!r} - {e}")
-
- # update plugin "database"
- self.write_plugins_json(processed_plugins, plug_dir)
-
- # generate output
- self.write_plugins_nix(processed_plugins, plug_dir)
-
- self.write_plugins_markdown(processed_plugins, plug_dir)
-
- self.line("<comment>Done</comment>")
-
- def write_plugins_markdown(self, plugins, plug_dir):
- """Write the list of all plugins to PLUGINS_LIST_FILE in markdown"""
-
- plugins.sort()
-
- self.line("<info>Updating plugins.md</info>")
-
- header = f" - Plugin count: {len(plugins)}\n\n| Repo | Last Update | Nix package name | Last checked |\n|:---|:---|:---|:---|\n"
-
- with open(get_const(PLUGINS_LIST_FILE, plug_dir), "w") as file:
- file.write(header)
- for plugin in plugins:
- file.write(f"{plugin.to_markdown()}\n")
-
- def write_plugins_nix(self, plugins, plug_dir):
- self.line("<info>Generating nix output</info>")
-
- plugins.sort()
-
- header = "{ lib, buildVimPlugin, fetchurl, fetchgit }: {"
- footer = "}"
-
- with open(get_const(PKGS_FILE, plug_dir), "w") as file:
- file.write(header)
- for plugin in plugins:
- file.write(f"{plugin.to_nix()}\n")
- file.write(footer)
-
- self.line("<info>Formatting nix output</info>")
-
- subprocess.run(
- ["alejandra", get_const(PKGS_FILE, plug_dir)],
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
-
- def write_plugins_json(self, plugins, plug_dir):
- self.line("<info>Storing results in .plugins.json</info>")
-
- plugins.sort()
-
- with open(get_const(JSON_FILE, plug_dir), "r+") as json_file:
- data = json.load(json_file)
-
- for plugin in plugins:
- data.update({f"{plugin.source_line}": plugin.to_json()})
-
- json_file.seek(0)
- json_file.write(json.dumps(data, indent=2, sort_keys=True))
- json_file.truncate()
-
- def check_duplicates(self, plugins):
- """check for duplicates in proccesed_plugins"""
- error = False
- for i, plugin in enumerate(plugins):
- for p in plugins[i + 1 :]:
- if plugin.name == p.name:
- self.line(
- f"<error>Error:</error> The following two lines produce the same plugin name:\n - {plugin.source_line}\n - {p.source_line}\n -> {p.name}"
- )
- error = True
-
- # We want to exit if the resulting nix file would be broken
- # But we want to go through all plugins before we do so
- if error:
- exit(1)
-
- def generate_plugin(self, spec, i, size, plug_dir):
- debug_string = ""
-
- processed_plugin = None
- failed_but_known = None
- failed_plugin = None
- try:
- debug_string += f" - <info>({i + 1}/{size}) Processing</info> {spec!r}\n"
- vim_plugin = plugin_from_spec(spec)
- debug_string += f" • <comment>Success</comment> {vim_plugin!r}\n"
- processed_plugin = vim_plugin
- except Exception as e:
- debug_string += f" • <error>Error:</error> Could not update <info>{spec.name}</info>. Keeping old values. Reason: {e}\n"
- with open(get_const(JSON_FILE, plug_dir), "r") as json_file:
- data = json.load(json_file)
-
- plugin_json = data.get(spec.line)
- if plugin_json:
- vim_plugin = jsonpickle.decode(plugin_json)
- processed_plugin = vim_plugin
- failed_but_known = (vim_plugin, e)
- else:
- debug_string += f" • <error>Error:</error> No entries for <info>{spec.name}</info> in '.plugins.json'. Skipping...\n"
- failed_plugin = (spec, e)
-
- self.line(debug_string.strip())
-
- return processed_plugin, failed_plugin, failed_but_known
-
- def process_manifest(self, spec_list, plug_dir):
- """Read specs in 'spec_list' and generate plugins"""
-
- size = len(spec_list)
-
- # We have to assume that we will reach an api limit. Therefore
- # we randomize the spec list to give every entry the same change to be updated and
- # not favor those at the start of the list
- shuffle(spec_list)
-
- with ThreadPoolExecutor() as executor:
- futures = [
- executor.submit(self.generate_plugin, spec, i, size, plug_dir) for i, spec in enumerate(spec_list)
- ]
- results = [future.result() for future in as_completed(futures)]
-
- processed_plugins = [r[0] for r in results]
- failed_plugins = [r[1] for r in results]
- failed_but_known = [r[2] for r in results]
-
- processed_plugins = list(filter(lambda x: x is not None, processed_plugins))
- failed_plugins = list(filter(lambda x: x is not None, failed_plugins))
- failed_but_known = list(filter(lambda x: x is not None, failed_but_known))
-
- processed_plugins.sort()
- failed_plugins.sort()
- failed_but_known.sort()
-
- assert len(processed_plugins) == len(spec_list) - len(failed_plugins)
-
- return processed_plugins, failed_plugins, failed_but_known