summary refs log tree commit diff
path: root/pkgs/applications/editors/vim/plugins/update.py
blob: f63bd867f3682a51fea2df80b9006afd4c832bb8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env nix-shell
#!nix-shell update-shell.nix -i python3


# format:
# $ nix run nixpkgs.python3Packages.black -c black update.py
# type-check:
# $ nix run nixpkgs.python3Packages.mypy -c mypy update.py
# linted:
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265,E402 update.py

# If you see `HTTP Error 429: too many requests` errors while running this script,
# refer to:
#
# https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md#updating-plugins-in-nixpkgs-updating-plugins-in-nixpkgs
#
# (or the equivalent file /doc/languages-frameworks/vim.section.md from Nixpkgs master tree).
#

import inspect
import os
import sys
import logging
import textwrap
from typing import List, Tuple
from pathlib import Path

log = logging.getLogger()

sh = logging.StreamHandler()
formatter = logging.Formatter('%(name)s:%(levelname)s: %(message)s')
sh.setFormatter(formatter)
log.addHandler(sh)

# Import plugin update library from maintainers/scripts/pluginupdate.py
ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
# Ideally, ROOT.(parent^5) points to root of Nixpkgs official tree
sys.path.insert(0, os.path.join(ROOT.parent.parent.parent.parent.parent, "maintainers", "scripts"))
import pluginupdate
from pluginupdate import run_nix_expr, PluginDesc

GET_PLUGINS = f"""(with import <localpkgs> {{}};
let
  inherit (vimUtils.override {{inherit vim;}}) buildNeovimPluginFrom2Nix buildVimPluginFrom2Nix;
  generated = callPackage {ROOT}/generated.nix {{
    inherit buildNeovimPluginFrom2Nix buildVimPluginFrom2Nix;
  }};
  hasChecksum = value: lib.isAttrs value && lib.hasAttrByPath ["src" "outputHash"] value;
  getChecksum = name: value:
    if hasChecksum value then {{
      submodules = value.src.fetchSubmodules or false;
      sha256 = value.src.outputHash;
      rev = value.src.rev;
    }} else null;
  checksums = lib.mapAttrs getChecksum generated;
in lib.filterAttrs (n: v: v != null) checksums)"""

GET_PLUGINS_LUA = """
with import <localpkgs> {};
lib.attrNames lua51Packages"""

HEADER = (
    "# This file has been generated by ./pkgs/applications/editors/vim/plugins/update.py. Do not edit!"
)

def isNeovimPlugin(plug: pluginupdate.Plugin) -> bool:
    '''
    Whether it's a neovim-only plugin
    We can check if it's available in lua packages
    '''
    global luaPlugins
    if plug.normalized_name in luaPlugins:
        log.debug("%s is a neovim plugin", plug)
        return True
    return False


class VimEditor(pluginupdate.Editor):
    def generate_nix(self, plugins: List[Tuple[PluginDesc, pluginupdate.Plugin]], outfile: str):
        sorted_plugins = sorted(plugins, key=lambda v: v[0].name.lower())

        with open(outfile, "w+") as f:
            f.write(HEADER)
            f.write(textwrap.dedent("""
                { lib, buildVimPluginFrom2Nix, buildNeovimPluginFrom2Nix, fetchFromGitHub, fetchgit }:

                final: prev:
                {
                """
            ))
            for pdesc, plugin in sorted_plugins:
                content = self.plugin2nix(pdesc, plugin)
                f.write(content)
            f.write("\n}\n")
        print(f"updated {outfile}")

    def plugin2nix(self, pdesc: PluginDesc, plugin: pluginupdate.Plugin) -> str:

        repo = pdesc.repo
        isNeovim = isNeovimPlugin(plugin)

        content = f"  {plugin.normalized_name} = "
        src_nix = repo.as_nix(plugin)
        content += """{buildFn} {{
    pname = "{plugin.name}";
    version = "{plugin.version}";
    src = {src_nix};
    meta.homepage = "{repo.uri}";
  }};

""".format(
        buildFn="buildNeovimPluginFrom2Nix" if isNeovim else "buildVimPluginFrom2Nix", plugin=plugin, src_nix=src_nix, repo=repo)
        print(content)
        return content

def main():

    global luaPlugins

    # whitelist
    luaPlugins = run_nix_expr(GET_PLUGINS_LUA) + [
        "diffview-nvim",
        "marks-nvim",
        "nvim-biscuits"
    ]

    editor = VimEditor("vim", ROOT, GET_PLUGINS)
    parser = editor.create_parser()
    args = parser.parse_args()
    pluginupdate.update_plugins(editor, args)


if __name__ == "__main__":
    main()