mirror of
https://github.com/nix-community/nixvim.git
synced 2025-07-09 08:44:32 +02:00
flake/dev/generate-all-maintainers: init
Used to generate a full maintainers.nix file that can be used for RFC39 invites. We will use these invites to support requesting reviews from maintainers.
This commit is contained in:
parent
95f129ca65
commit
056cd86cc0
5 changed files with 328 additions and 0 deletions
|
@ -51,6 +51,7 @@
|
|||
packages = lib.optionalAttrs (partitionStack == [ ]) {
|
||||
# Propagate `packages` from the `dev` partition:
|
||||
inherit (config.partitions.dev.module.flake.packages.${system})
|
||||
generate-all-maintainers
|
||||
list-plugins
|
||||
;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{
|
||||
imports = [
|
||||
./devshell.nix
|
||||
./generate-all-maintainers
|
||||
./list-plugins
|
||||
./package-tests.nix
|
||||
./template-tests.nix
|
||||
|
|
42
flake/dev/generate-all-maintainers/default.nix
Normal file
42
flake/dev/generate-all-maintainers/default.nix
Normal file
|
@ -0,0 +1,42 @@
|
|||
{ self, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
package = pkgs.writers.writePython3Bin "generate-all-maintainers" {
|
||||
# Disable flake8 checks that are incompatible with the ruff ones
|
||||
flakeIgnore = [
|
||||
# Thinks shebang is a block comment
|
||||
"E265"
|
||||
# line too long
|
||||
"E501"
|
||||
# line break before binary operator
|
||||
"W503"
|
||||
];
|
||||
} (builtins.readFile ./generate-all-maintainers.py);
|
||||
in
|
||||
{
|
||||
packages.generate-all-maintainers = package;
|
||||
|
||||
checks.generate-all-maintainers-test =
|
||||
pkgs.runCommand "generate-all-maintainers-test"
|
||||
{
|
||||
nativeBuildInputs = [ package ];
|
||||
}
|
||||
''
|
||||
generate-all-maintainers --root ${self} --output $out
|
||||
'';
|
||||
|
||||
devshells.default.commands = [
|
||||
{
|
||||
name = "generate-all-maintainers";
|
||||
command = ''${lib.getExe package} "$@"'';
|
||||
help = "Generate a single nix file with all `nixvim` and `nixpkgs` maintainer entries";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
# Extract maintainers from nixvim configuration using meta.maintainers
|
||||
# This script evaluates an empty nixvimConfiguration and extracts the merged maintainer information
|
||||
let
|
||||
nixvim = import ../../..;
|
||||
lib = nixvim.inputs.nixpkgs.lib.extend nixvim.lib.overlay;
|
||||
|
||||
emptyConfig = lib.nixvim.evalNixvim {
|
||||
modules = [ { _module.check = false; } ];
|
||||
extraSpecialArgs = {
|
||||
pkgs = null;
|
||||
};
|
||||
};
|
||||
|
||||
inherit (emptyConfig.config.meta) maintainers;
|
||||
|
||||
extractMaintainerObjects =
|
||||
maintainerData:
|
||||
lib.pipe maintainerData [
|
||||
lib.attrValues
|
||||
lib.concatLists
|
||||
lib.unique
|
||||
];
|
||||
|
||||
allMaintainerObjects = extractMaintainerObjects maintainers;
|
||||
|
||||
allMaintainerNames = lib.filter (name: name != null) (
|
||||
map (maintainer: maintainer.github) allMaintainerObjects
|
||||
);
|
||||
|
||||
nixvimMaintainers = import ../../../lib/maintainers.nix;
|
||||
nixvimMaintainerNames = lib.attrNames nixvimMaintainers;
|
||||
partitionedMaintainers = lib.partition (nameValue: lib.elem nameValue.name nixvimMaintainerNames) (
|
||||
lib.attrsToList maintainerDetails
|
||||
);
|
||||
|
||||
maintainerDetails = lib.pipe allMaintainerObjects [
|
||||
(map (obj: {
|
||||
name = obj.github;
|
||||
value = obj // {
|
||||
source =
|
||||
if categorizedMaintainers.nixvim ? ${obj.github} then
|
||||
"nixvim"
|
||||
else if categorizedMaintainers.nixpkgs ? ${obj.github} then
|
||||
"nixpkgs"
|
||||
else
|
||||
throw "${obj.github} is neither a nixvim or nixpkgs maintainer";
|
||||
};
|
||||
}))
|
||||
lib.listToAttrs
|
||||
];
|
||||
|
||||
categorizedMaintainers = {
|
||||
nixvim = lib.listToAttrs partitionedMaintainers.right;
|
||||
nixpkgs = lib.listToAttrs partitionedMaintainers.wrong;
|
||||
};
|
||||
|
||||
formattedMaintainers = lib.generators.toPretty {
|
||||
multiline = true;
|
||||
indent = "";
|
||||
} maintainerDetails;
|
||||
in
|
||||
{
|
||||
raw = maintainers;
|
||||
names = allMaintainerNames;
|
||||
details = maintainerDetails;
|
||||
categorized = categorizedMaintainers;
|
||||
formatted = formattedMaintainers;
|
||||
|
||||
stats = {
|
||||
totalMaintainers = lib.length allMaintainerNames;
|
||||
nixvimMaintainers = lib.length (lib.attrNames categorizedMaintainers.nixvim);
|
||||
nixpkgsMaintainers = lib.length (lib.attrNames categorizedMaintainers.nixpkgs);
|
||||
};
|
||||
}
|
210
flake/dev/generate-all-maintainers/generate-all-maintainers.py
Executable file
210
flake/dev/generate-all-maintainers/generate-all-maintainers.py
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p python3
|
||||
"""
|
||||
Generate all-maintainers.nix using meta.maintainers as source of truth.
|
||||
|
||||
This script uses the meta.maintainers system to extract maintainer information
|
||||
by evaluating an empty nixvimConfiguration, which is much simpler and more
|
||||
reliable than parsing files with regex.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import inspect
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_project_root() -> Path:
|
||||
"""
|
||||
Find the project root directory.
|
||||
|
||||
Tries to find the git repository root. If that fails, falls back to
|
||||
locating it relative to this script file.
|
||||
"""
|
||||
try:
|
||||
# Ask git for the top-level directory of the current repository.
|
||||
git_root_bytes = subprocess.check_output(
|
||||
["git", "rev-parse", "--show-toplevel"], stderr=subprocess.DEVNULL
|
||||
)
|
||||
return Path(git_root_bytes.decode("utf-8").strip())
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
# Fallback for when not in a git repo or git is not installed.
|
||||
print(
|
||||
"Warning: 'git rev-parse --show-toplevel' failed.",
|
||||
"Falling back to script location to determine root.",
|
||||
"This may not work correctly with flakes.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
# Assumes this script is at: <root>/flake/dev/generate-all-maintainers/
|
||||
return Path(__file__).parent.parent.parent.parent.resolve()
|
||||
|
||||
|
||||
class MetaMaintainerGenerator:
|
||||
"""Generates maintainers list using meta.maintainers from nixvim evaluation."""
|
||||
|
||||
def __init__(self, nixvim_root: Path):
|
||||
self.nixvim_root = nixvim_root
|
||||
self.nixvim_maintainers_file = nixvim_root / "lib" / "maintainers.nix"
|
||||
self.output_file = nixvim_root / "generated" / "all-maintainers.nix"
|
||||
self.extractor_script = (
|
||||
nixvim_root
|
||||
/ "flake"
|
||||
/ "dev"
|
||||
/ "generate-all-maintainers"
|
||||
/ "extract-maintainers-meta.nix"
|
||||
)
|
||||
|
||||
def extract_maintainers_from_meta(self) -> dict:
|
||||
"""Extract maintainer information using meta.maintainers."""
|
||||
print("🔍 Extracting maintainers using meta.maintainers...")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--file",
|
||||
str(self.extractor_script),
|
||||
"--json",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
data = json.loads(result.stdout)
|
||||
print("✅ Successfully extracted maintainers using meta.maintainers")
|
||||
return data
|
||||
else:
|
||||
print(f"❌ Failed to extract maintainers: {result.stderr}")
|
||||
sys.exit(1)
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
print("❌ Timeout while extracting maintainers")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ Error extracting maintainers: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def generate_maintainers_file(self) -> None:
|
||||
"""Generate the complete all-maintainers.nix file."""
|
||||
print("📄 Generating all-maintainers.nix using meta.maintainers...")
|
||||
|
||||
# Extract maintainers using meta.maintainers
|
||||
maintainer_data = self.extract_maintainers_from_meta()
|
||||
|
||||
nixvim_maintainers = maintainer_data["categorized"]["nixvim"]
|
||||
nixpkgs_maintainers = maintainer_data["categorized"]["nixpkgs"]
|
||||
formatted_maintainers = maintainer_data["formatted"]
|
||||
|
||||
print(f"🏠 Nixvim maintainers: {len(nixvim_maintainers)}")
|
||||
print(f"📦 Nixpkgs maintainers: {len(nixpkgs_maintainers)}")
|
||||
|
||||
with open(self.output_file, "w") as f:
|
||||
f.write(inspect.cleandoc("""
|
||||
# Nixvim all maintainers list.
|
||||
#
|
||||
# This file lists all referenced maintainers in Nixvim.
|
||||
#
|
||||
# This file is automatically generated using meta.maintainers from nixvim evaluation
|
||||
# DO NOT EDIT MANUALLY
|
||||
#
|
||||
# To regenerate: nix run .#generate-all-maintainers
|
||||
#
|
||||
"""))
|
||||
|
||||
# Use the formatted maintainers from Nix evaluation
|
||||
print(
|
||||
"✨ Serializing formatted maintainers using lib.generators.toPretty..."
|
||||
)
|
||||
f.write("\n")
|
||||
f.write(formatted_maintainers)
|
||||
f.write("\n")
|
||||
|
||||
self.validate_generated_file()
|
||||
self.print_statistics(maintainer_data)
|
||||
|
||||
def validate_generated_file(self) -> bool:
|
||||
"""Validate the generated Nix file syntax."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nix-instantiate", "--eval", str(self.output_file), "--strict"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print("✅ Generated file has valid Nix syntax")
|
||||
return True
|
||||
else:
|
||||
print("❌ Warning: Generated file has Nix syntax errors")
|
||||
print(result.stderr[:500])
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not validate file: {e}")
|
||||
return False
|
||||
|
||||
def print_statistics(self, maintainer_data: dict) -> None:
|
||||
"""Print generation statistics."""
|
||||
stats = maintainer_data["stats"]
|
||||
|
||||
print(f"✅ Generated {self.output_file}")
|
||||
print("📊 Statistics:")
|
||||
print(f" - Total unique maintainers: {stats['totalMaintainers']}")
|
||||
print(f" - Nixvim maintainers: {stats['nixvimMaintainers']}")
|
||||
print(f" - Nixpkgs maintainers: {stats['nixpkgsMaintainers']}")
|
||||
print()
|
||||
print("🎉 Generation completed successfully using meta.maintainers!")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate Nixvim all-maintainers.nix using meta.maintainers"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--root",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Path to Nixvim root (default: auto-detect)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Output file path (default: <root>/generated/all-maintainers.nix)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.root:
|
||||
nixvim_root = args.root
|
||||
else:
|
||||
nixvim_root = get_project_root()
|
||||
|
||||
if not (nixvim_root / "lib" / "maintainers.nix").exists():
|
||||
print(f"Error: Could not find maintainers.nix in {nixvim_root}")
|
||||
print("Please specify --root or run from Nixvim directory")
|
||||
sys.exit(1)
|
||||
|
||||
generator = MetaMaintainerGenerator(nixvim_root)
|
||||
if args.output:
|
||||
generator.output_file = args.output
|
||||
|
||||
print("🚀 Generating maintainers using meta.maintainers approach...")
|
||||
|
||||
try:
|
||||
generator.generate_maintainers_file()
|
||||
except KeyboardInterrupt:
|
||||
print("\n❌ Generation cancelled by user")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ Error generating maintainers file: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue