vim/update.py: distinguish between vim/neovim plugins

I've been working for a long time towards automatic nix dependencies for
neovim plugins (using luarocks rockspecs to discover the said
dependencies).
This is an initial commit to help me complete the missing bits.
buildNeovimPluginFrom2Nix is right now a placeholder which helps me test
in my fork a version that does a flat install of luarocks.

the vim updater will now check for attributes with the same name in the lua package set,
if that's the case the script will generate buildNeovimPluginFrom2Nix.
This commit is contained in:
Matthieu Coudron 2022-05-02 00:58:41 +02:00
parent b9e29b16ba
commit d4894355c1
4 changed files with 67 additions and 23 deletions

View File

@ -311,6 +311,16 @@ def load_plugins_from_csv(config: FetchConfig, input_file: Path,) -> List[Plugin
return plugins
def run_nix_expr(expr):
with CleanEnvironment():
cmd = ["nix", "eval", "--extra-experimental-features",
"nix-command", "--impure", "--json", "--expr", expr]
log.debug("Running command %s", cmd)
out = subprocess.check_output(cmd)
data = json.loads(out)
return data
class Editor:
"""The configuration of the update script."""
@ -333,13 +343,9 @@ class Editor:
self.deprecated = deprecated or root.joinpath("deprecated.json")
self.cache_file = cache_file or f"{name}-plugin-cache.json"
def get_current_plugins(editor) -> List[Plugin]:
def get_current_plugins(self) -> List[Plugin]:
"""To fill the cache"""
with CleanEnvironment():
cmd = ["nix", "eval", "--extra-experimental-features", "nix-command", "--impure", "--json", "--expr", editor.get_plugins]
log.debug("Running command %s", cmd)
out = subprocess.check_output(cmd)
data = json.loads(out)
data = run_nix_expr(self.get_plugins)
plugins = []
for name, attr in data.items():
print("get_current_plugins: name %s" % name)

View File

@ -3,7 +3,8 @@
let
inherit (vimUtils.override {inherit vim;}) buildVimPluginFrom2Nix vimGenDocHook vimCommandCheckHook;
inherit (vimUtils.override {inherit vim;})
buildVimPluginFrom2Nix vimGenDocHook vimCommandCheckHook;
inherit (lib) extends;
@ -24,6 +25,7 @@ let
plugins = callPackage ./generated.nix {
inherit buildVimPluginFrom2Nix;
inherit (vimUtils) buildNeovimPluginFrom2Nix;
};
# TL;DR

View File

@ -26,19 +26,24 @@ from typing import List, Tuple
from pathlib import Path
log = logging.getLogger()
log.addHandler(logging.StreamHandler())
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;}}) buildVimPluginFrom2Nix;
inherit (vimUtils.override {{inherit vim;}}) buildNeovimPluginFrom2Nix buildVimPluginFrom2Nix;
generated = callPackage {ROOT}/generated.nix {{
inherit buildVimPluginFrom2Nix;
inherit buildNeovimPluginFrom2Nix buildVimPluginFrom2Nix;
}};
hasChecksum = value: lib.isAttrs value && lib.hasAttrByPath ["src" "outputHash"] value;
getChecksum = name: value:
@ -50,43 +55,69 @@ let
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[pluginupdate.PluginDesc, pluginupdate.Plugin]], outfile: str):
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, fetchFromGitHub, fetchgit }:
{ 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}")
repo = pdesc.repo
src_nix = repo.as_nix(plugin)
f.write(
f"""
{plugin.normalized_name} = buildVimPluginFrom2Nix {{
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}";
}};
"""
)
f.write("\n}\n")
print(f"updated {outfile}")
""".format(
buildFn="buildNeovimPluginFrom2Nix" if isNeovim else "buildVimPluginFrom2Nix", plugin=plugin, src_nix=src_nix, repo=repo)
print(content)
return content
def main():
global luaPlugins
luaPlugins = run_nix_expr(GET_PLUGINS_LUA)
editor = VimEditor("vim", ROOT, GET_PLUGINS)
parser = editor.create_parser()
args = parser.parse_args()

View File

@ -535,6 +535,11 @@ rec {
inherit lib stdenv rtpPath vim vimGenDocHook vimCommandCheckHook;
}) buildVimPlugin buildVimPluginFrom2Nix;
# TODO placeholder to ease working on automatic plugin detection
# this should be a luarocks "flat" install with appropriate vim hooks
buildNeovimPluginFrom2Nix = buildVimPluginFrom2Nix;
# used to figure out which python dependencies etc. neovim needs
requiredPlugins = {
packages ? {},