mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 11:36:05 +01:00
ci: extract-maintainers-meta tweaks (#7434)
Simplify extraction and generation of file. We dont need the comments and can leverage the appropriate lib.generator function. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
parent
9d343f0880
commit
b8b7e5ec35
2 changed files with 71 additions and 64 deletions
|
|
@ -13,6 +13,7 @@ let
|
||||||
moduleMaintainersJson = builtins.fromJSON (builtins.readFile docsLib.jsonModuleMaintainers);
|
moduleMaintainersJson = builtins.fromJSON (builtins.readFile docsLib.jsonModuleMaintainers);
|
||||||
maintainers = moduleMaintainersJson;
|
maintainers = moduleMaintainersJson;
|
||||||
|
|
||||||
|
# TODO: Find a better solution for extracting maintainers outside `modules`
|
||||||
additionalFiles = [
|
additionalFiles = [
|
||||||
../../docs/home-manager-manual.nix
|
../../docs/home-manager-manual.nix
|
||||||
];
|
];
|
||||||
|
|
@ -58,22 +59,30 @@ let
|
||||||
|
|
||||||
allMaintainerObjects = extractMaintainerObjects maintainers ++ additionalMaintainerObjects;
|
allMaintainerObjects = extractMaintainerObjects maintainers ++ additionalMaintainerObjects;
|
||||||
|
|
||||||
getMaintainerName = maintainer: maintainer.github or maintainer.name or null;
|
allMaintainerNames = lib.filter (name: name != null) (
|
||||||
|
map (maintainer: maintainer.github or maintainer.name or null) allMaintainerObjects
|
||||||
allMaintainerNames = lib.filter (name: name != null) (map getMaintainerName allMaintainerObjects);
|
);
|
||||||
|
|
||||||
maintainerDetails = lib.pipe allMaintainerObjects [
|
|
||||||
(lib.filter (obj: getMaintainerName obj != null))
|
|
||||||
(map (obj: {
|
|
||||||
name = getMaintainerName obj;
|
|
||||||
value = obj;
|
|
||||||
}))
|
|
||||||
lib.listToAttrs
|
|
||||||
];
|
|
||||||
|
|
||||||
hmMaintainers = import ../../modules/lib/maintainers.nix;
|
hmMaintainers = import ../../modules/lib/maintainers.nix;
|
||||||
hmMaintainerNames = lib.attrNames hmMaintainers;
|
hmMaintainerNames = lib.attrNames hmMaintainers;
|
||||||
|
|
||||||
|
maintainerDetails = lib.pipe allMaintainerObjects [
|
||||||
|
(lib.filter (obj: (obj.github or obj.name or null) != null))
|
||||||
|
(map (obj: {
|
||||||
|
name = obj.github or obj.name;
|
||||||
|
value = obj // {
|
||||||
|
source =
|
||||||
|
if categorizedMaintainers.home-manager ? ${obj.github} then
|
||||||
|
"home-manager"
|
||||||
|
else if categorizedMaintainers.nixpkgs ? ${obj.github} then
|
||||||
|
"nixpkgs"
|
||||||
|
else
|
||||||
|
throw "${obj.github} is neither a home-manager or nixpkgs maintainer";
|
||||||
|
};
|
||||||
|
}))
|
||||||
|
lib.listToAttrs
|
||||||
|
];
|
||||||
|
|
||||||
partitionedMaintainers = lib.partition (nameValue: lib.elem nameValue.name hmMaintainerNames) (
|
partitionedMaintainers = lib.partition (nameValue: lib.elem nameValue.name hmMaintainerNames) (
|
||||||
lib.attrsToList maintainerDetails
|
lib.attrsToList maintainerDetails
|
||||||
);
|
);
|
||||||
|
|
@ -83,35 +92,10 @@ let
|
||||||
nixpkgs = lib.listToAttrs partitionedMaintainers.wrong;
|
nixpkgs = lib.listToAttrs partitionedMaintainers.wrong;
|
||||||
};
|
};
|
||||||
|
|
||||||
formatMaintainer =
|
formattedMaintainers = lib.generators.toPretty {
|
||||||
name: info: source:
|
multiline = true;
|
||||||
let
|
indent = "";
|
||||||
quotedName =
|
} maintainerDetails;
|
||||||
if lib.match "[0-9].*" name != null || lib.match "[^a-zA-Z0-9_-].*" name != null then
|
|
||||||
''"${name}"''
|
|
||||||
else
|
|
||||||
name;
|
|
||||||
|
|
||||||
filteredInfo = lib.filterAttrs (k: v: !lib.hasPrefix "_" k) info;
|
|
||||||
in
|
|
||||||
" ${quotedName} = ${
|
|
||||||
lib.generators.toPretty {
|
|
||||||
multiline = true;
|
|
||||||
indent = " ";
|
|
||||||
} filteredInfo
|
|
||||||
};";
|
|
||||||
|
|
||||||
formatAllMaintainers =
|
|
||||||
let
|
|
||||||
hmEntries = lib.mapAttrsToList (
|
|
||||||
name: info: formatMaintainer name info "home-manager"
|
|
||||||
) categorizedMaintainers.home-manager;
|
|
||||||
|
|
||||||
nixpkgsEntries = lib.mapAttrsToList (
|
|
||||||
name: info: formatMaintainer name info "nixpkgs"
|
|
||||||
) categorizedMaintainers.nixpkgs;
|
|
||||||
in
|
|
||||||
lib.concatStringsSep "\n" (hmEntries ++ nixpkgsEntries);
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
@ -119,7 +103,7 @@ in
|
||||||
names = allMaintainerNames;
|
names = allMaintainerNames;
|
||||||
details = maintainerDetails;
|
details = maintainerDetails;
|
||||||
categorized = categorizedMaintainers;
|
categorized = categorizedMaintainers;
|
||||||
formatted = formatAllMaintainers;
|
formatted = formattedMaintainers;
|
||||||
|
|
||||||
stats = {
|
stats = {
|
||||||
totalFiles = lib.length (lib.attrNames maintainers);
|
totalFiles = lib.length (lib.attrNames maintainers);
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,37 @@ reliable than parsing files with regex.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import inspect
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
class MetaMaintainerGenerator:
|
||||||
"""Generates maintainers list using meta.maintainers from Home Manager evaluation."""
|
"""Generates maintainers list using meta.maintainers from Home Manager evaluation."""
|
||||||
|
|
||||||
|
|
@ -25,13 +49,13 @@ class MetaMaintainerGenerator:
|
||||||
self.output_file = hm_root / "all-maintainers.nix"
|
self.output_file = hm_root / "all-maintainers.nix"
|
||||||
self.extractor_script = hm_root / "lib" / "nix" / "extract-maintainers-meta.nix"
|
self.extractor_script = hm_root / "lib" / "nix" / "extract-maintainers-meta.nix"
|
||||||
|
|
||||||
def extract_maintainers_from_meta(self) -> Dict:
|
def extract_maintainers_from_meta(self) -> dict:
|
||||||
"""Extract maintainer information using meta.maintainers."""
|
"""Extract maintainer information using meta.maintainers."""
|
||||||
print("🔍 Extracting maintainers using meta.maintainers...")
|
print("🔍 Extracting maintainers using meta.maintainers...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run([
|
result = subprocess.run([
|
||||||
"nix", "eval", "--impure", "--file", str(self.extractor_script), "--json"
|
"nix", "eval", "--file", str(self.extractor_script), "--json"
|
||||||
], capture_output=True, text=True, timeout=60)
|
], capture_output=True, text=True, timeout=60)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
|
|
@ -49,7 +73,7 @@ class MetaMaintainerGenerator:
|
||||||
print(f"❌ Error extracting maintainers: {e}")
|
print(f"❌ Error extracting maintainers: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def format_maintainer_entry(self, name: str, info: Dict, source: str) -> str:
|
def format_maintainer_entry(self, name: str, info: dict, source: str) -> str:
|
||||||
"""Format a single maintainer entry with nix fmt compatible formatting."""
|
"""Format a single maintainer entry with nix fmt compatible formatting."""
|
||||||
lines = [f" # {source}"]
|
lines = [f" # {source}"]
|
||||||
lines.append(f" {name} = {{")
|
lines.append(f" {name} = {{")
|
||||||
|
|
@ -116,26 +140,26 @@ class MetaMaintainerGenerator:
|
||||||
print(f"📦 Nixpkgs maintainers: {len(nixpkgs_maintainers)}")
|
print(f"📦 Nixpkgs maintainers: {len(nixpkgs_maintainers)}")
|
||||||
|
|
||||||
with open(self.output_file, 'w') as f:
|
with open(self.output_file, 'w') as f:
|
||||||
f.write('''# Home Manager all maintainers list.
|
f.write(
|
||||||
#
|
inspect.cleandoc("""
|
||||||
# This file lists all referenced maintainers in Home Manager.
|
# Home Manager all maintainers list.
|
||||||
#
|
#
|
||||||
# This file is automatically generated using meta.maintainers from Home Manager evaluation
|
# This file lists all referenced maintainers in Home Manager.
|
||||||
# DO NOT EDIT MANUALLY
|
#
|
||||||
#
|
# This file is automatically generated using meta.maintainers from Home Manager evaluation
|
||||||
# To regenerate: ./lib/python/generate-all-maintainers.py
|
# DO NOT EDIT MANUALLY
|
||||||
#
|
#
|
||||||
{
|
# To regenerate: ./lib/python/generate-all-maintainers.py
|
||||||
''')
|
#
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
|
||||||
# Use the formatted maintainers from Nix evaluation
|
# Use the formatted maintainers from Nix evaluation
|
||||||
print("✨ Adding formatted maintainers using lib.generators.toPretty...")
|
print("✨ Adding formatted maintainers using lib.generators.toPretty...")
|
||||||
|
f.write("\n")
|
||||||
f.write(formatted_maintainers)
|
f.write(formatted_maintainers)
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
f.write('''}
|
|
||||||
''')
|
|
||||||
|
|
||||||
self.validate_generated_file()
|
self.validate_generated_file()
|
||||||
self.print_statistics(maintainer_data)
|
self.print_statistics(maintainer_data)
|
||||||
|
|
||||||
|
|
@ -143,7 +167,7 @@ class MetaMaintainerGenerator:
|
||||||
"""Validate the generated Nix file syntax."""
|
"""Validate the generated Nix file syntax."""
|
||||||
try:
|
try:
|
||||||
result = subprocess.run([
|
result = subprocess.run([
|
||||||
'nix', 'eval', '--file', str(self.output_file), '--json'
|
'nix-instantiate', '--eval', str(self.output_file), '--strict'
|
||||||
], capture_output=True, text=True, timeout=10)
|
], capture_output=True, text=True, timeout=10)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
|
|
@ -157,7 +181,7 @@ class MetaMaintainerGenerator:
|
||||||
print(f"Warning: Could not validate file: {e}")
|
print(f"Warning: Could not validate file: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def print_statistics(self, maintainer_data: Dict) -> None:
|
def print_statistics(self, maintainer_data: dict) -> None:
|
||||||
"""Print generation statistics."""
|
"""Print generation statistics."""
|
||||||
stats = maintainer_data["stats"]
|
stats = maintainer_data["stats"]
|
||||||
|
|
||||||
|
|
@ -193,8 +217,7 @@ def main():
|
||||||
if args.root:
|
if args.root:
|
||||||
hm_root = args.root
|
hm_root = args.root
|
||||||
else:
|
else:
|
||||||
script_dir = Path(__file__).parent
|
hm_root = get_project_root()
|
||||||
hm_root = script_dir.parent.parent
|
|
||||||
|
|
||||||
if not (hm_root / "modules" / "lib" / "maintainers.nix").exists():
|
if not (hm_root / "modules" / "lib" / "maintainers.nix").exists():
|
||||||
print(f"Error: Could not find maintainers.nix in {hm_root}")
|
print(f"Error: Could not find maintainers.nix in {hm_root}")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue