Skip to content

Commit a473ef6

Browse files
committed
flake: add diff-plugins command
Prints the plugins added or removed when compared to a particular nixvim revision.
1 parent f0764db commit a473ef6

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

flake/dev/devshell.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@
115115
command = ''${pkgs.python3.interpreter} ${./new-plugin.py} "$@"'';
116116
help = "Create a new plugin";
117117
}
118+
{
119+
name = "diff-plugins";
120+
command = ''${pkgs.python3.interpreter} ${./diff-plugins.py} "$@"'';
121+
help = "Compare available plugins with another nixvim commit";
122+
}
118123
];
119124
};
120125
};

flake/dev/diff-plugins.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env python3
2+
3+
import json
4+
import re
5+
import subprocess
6+
from argparse import ArgumentParser, ArgumentTypeError
7+
8+
9+
def main():
10+
"""
11+
Main function to compare nixvim plugins with another revision.
12+
"""
13+
14+
parser = ArgumentParser(description="Compare nixvim plugins with another revision")
15+
parser.add_argument(
16+
"flakeref",
17+
metavar="old",
18+
help="the commit or flakeref to compare against",
19+
type=flakeref,
20+
)
21+
parser.add_argument(
22+
"--compact",
23+
"-c",
24+
help="produce compact json instead of prettifying",
25+
action="store_true",
26+
)
27+
args = parser.parse_args()
28+
29+
after_plugins = list_plugins(".")
30+
before_plugins = list_plugins(args.flakeref)
31+
print(
32+
json.dumps(
33+
diff(before_plugins, after_plugins),
34+
separators=((",", ":") if args.compact else None),
35+
indent=(None if args.compact else 4),
36+
sort_keys=(not args.compact),
37+
default=list,
38+
)
39+
)
40+
41+
42+
def flakeref(arg):
43+
"""
44+
An argparse type that represents a flakeref, or a partial flakeref that we can
45+
normalise using sane defaults.
46+
"""
47+
default_protocol = "github:"
48+
default_repo = "nix-community/nixvim"
49+
sha_rxp = re.compile(r"^[A-Fa-f0-9]{6,40}$")
50+
repo_rxp = re.compile(
51+
r"^(?P<protocol>[^:/]+:)?(?P<repo>(:?[^/]+)/(:?[^/]+))(?P<sha>/[A-Fa-f0-9]{6,40})?$"
52+
)
53+
if sha_rxp.match(arg):
54+
return f"{default_protocol}{default_repo}/{arg}"
55+
elif m := repo_rxp.match(arg):
56+
protocol = m.group("protocol") or default_protocol
57+
repo = m.group("repo")
58+
sha = m.group("sha") or ""
59+
return protocol + repo + sha
60+
else:
61+
raise ArgumentTypeError(f"Unsupported commit or flakeref format: {arg}")
62+
63+
64+
def diff(before: list[str], after: list[str]):
65+
"""
66+
Compare the before and after plugin sets.
67+
"""
68+
# TODO: also guess at "renamed" plugins heuristically
69+
return {
70+
"added": {n: after[n] - before[n] for n in ["plugins", "colorschemes"]},
71+
"removed": {n: before[n] - after[n] for n in ["plugins", "colorschemes"]},
72+
}
73+
74+
75+
def list_plugins(flake: str) -> list[str]:
76+
"""
77+
Gets a list of plugins that exist in the flake.
78+
Grouped as "plugins" and "colorschemes"
79+
"""
80+
expr = """
81+
options:
82+
builtins.listToAttrs (
83+
map
84+
(name: {
85+
inherit name;
86+
value = builtins.attrNames options.${name};
87+
})
88+
[
89+
"plugins"
90+
"colorschemes"
91+
]
92+
)
93+
"""
94+
cmd = [
95+
"nix",
96+
"eval",
97+
f"{flake}#nixvimConfiguration.options",
98+
"--apply",
99+
expr,
100+
"--json",
101+
]
102+
out = subprocess.check_output(cmd)
103+
# Parse as json, converting the lists to sets
104+
return {k: set(v) for k, v in json.loads(out).items()}
105+
106+
107+
if __name__ == "__main__":
108+
main()

0 commit comments

Comments
 (0)