mirror of
https://github.com/lilydjwg/nvchecker.git
synced 2025-03-10 06:14:02 +00:00
wip: impl nix expr writer
This commit is contained in:
parent
de1a3c6fc2
commit
5d3abd56f6
2 changed files with 103 additions and 1 deletions
|
@ -91,6 +91,9 @@ def main() -> None:
|
||||||
vers.update(results)
|
vers.update(results)
|
||||||
core.write_verfile(newverf, vers)
|
core.write_verfile(newverf, vers)
|
||||||
|
|
||||||
|
if options.nix_expr_folder is not None:
|
||||||
|
core.write_nix_expr_files(options, entries, results)
|
||||||
|
|
||||||
if args.failures and has_failures:
|
if args.failures and has_failures:
|
||||||
sys.exit(3)
|
sys.exit(3)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
from asyncio import Queue
|
from asyncio import Queue
|
||||||
import logging
|
import logging
|
||||||
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
from typing import (
|
from typing import (
|
||||||
Tuple, NamedTuple, Optional, List, Union,
|
Tuple, NamedTuple, Optional, List, Union,
|
||||||
|
@ -21,6 +22,8 @@ import re
|
||||||
import contextvars
|
import contextvars
|
||||||
import json
|
import json
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import string
|
||||||
|
import urllib
|
||||||
|
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
|
@ -172,6 +175,95 @@ def json_encode(obj):
|
||||||
return d
|
return d
|
||||||
raise TypeError(obj)
|
raise TypeError(obj)
|
||||||
|
|
||||||
|
def lock_source_nix(type: str, ref: str, target: str) -> str:
|
||||||
|
if type in ["github", "gitlab"]:
|
||||||
|
owner, _, repo = target.rpartition("/")
|
||||||
|
owner = urllib.parse.quote_plus(owner)
|
||||||
|
ref = urllib.parse.quote_plus(ref)
|
||||||
|
fetchtree = f'type = "{type}"; owner = "{owner}"; repo = "{repo}"; ref = "{ref}";'
|
||||||
|
nix = (
|
||||||
|
f'owner = "{owner}";'
|
||||||
|
f' repo = "{repo}";'
|
||||||
|
)
|
||||||
|
if type in ["git"]:
|
||||||
|
url = target
|
||||||
|
fetchtree = f'type = "{type}"; url = "{url}"; ref = "{ref}"; shallow = true;'
|
||||||
|
nix = (
|
||||||
|
f'url = "{url}";'
|
||||||
|
)
|
||||||
|
|
||||||
|
command = [
|
||||||
|
'nix',
|
||||||
|
'eval',
|
||||||
|
'--impure',
|
||||||
|
'--json',
|
||||||
|
'--expr',
|
||||||
|
# removing outPath ensures the stringer renders the entire attrset
|
||||||
|
'builtins.removeAttrs (builtins.fetchTree {' + fetchtree + '}) ["outPath"]'
|
||||||
|
]
|
||||||
|
tmpl = string.Template("""
|
||||||
|
type = "$type";
|
||||||
|
$nix
|
||||||
|
narHash = "$narHash";
|
||||||
|
rev = "$rev";""")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(command, check=True, capture_output=True, text=True)
|
||||||
|
output = json.loads(result.stdout)
|
||||||
|
return tmpl.substitute(type=type, nix=nix, **output)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
error_message = "Locking the source in nix failed; stderr from the nix command: \n"
|
||||||
|
error_message += e.stderr
|
||||||
|
logger.error(error_message, type=type, ref=ref)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def write_nix_expr_files(opt: Options, entries: Entries, results: ResultData) -> None:
|
||||||
|
oldvers = {}
|
||||||
|
if opt.ver_files is not None:
|
||||||
|
oldverf = opt.ver_files[0]
|
||||||
|
newverf = opt.ver_files[1]
|
||||||
|
oldvers = read_verfile(oldverf)
|
||||||
|
newvers = read_verfile(newverf)
|
||||||
|
|
||||||
|
names = []
|
||||||
|
tmpl = string.Template("""
|
||||||
|
pname = "$name";
|
||||||
|
version = "$version";
|
||||||
|
meta = {
|
||||||
|
url = "$url";
|
||||||
|
description = "Sources for $name ($version)";
|
||||||
|
};
|
||||||
|
src = builtins.fetchTree {$fetchTreeArgs
|
||||||
|
};
|
||||||
|
passthru = builtins.fromJSON ''$passthru'';""")
|
||||||
|
for name, r in results.items():
|
||||||
|
oldver = oldvers.get(name, None)
|
||||||
|
if not oldver or oldver != r:
|
||||||
|
conf = entries.get(name)
|
||||||
|
file = opt.nix_expr_folder / (name + ".nix")
|
||||||
|
logger.info("update nix", name=name, file=file)
|
||||||
|
type = conf.get("source")
|
||||||
|
target = conf.get(type)
|
||||||
|
ref = r.gitref or r.revision or r.version
|
||||||
|
try:
|
||||||
|
fetchTreeArgs=lock_source_nix(type, ref, target)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
data = '{'
|
||||||
|
data += tmpl.substitute(
|
||||||
|
name=name,
|
||||||
|
version=r.version,
|
||||||
|
url=r.url,
|
||||||
|
fetchTreeArgs=fetchTreeArgs,
|
||||||
|
passthru=json.dumps(conf.get("passthru", {})),
|
||||||
|
)
|
||||||
|
data += '\n}'
|
||||||
|
safe_overwrite(file, data)
|
||||||
|
names.append(name)
|
||||||
|
if opt.ver_files is not None:
|
||||||
|
oldvers[name] = r
|
||||||
|
if opt.ver_files is not None:
|
||||||
|
write_verfile(oldverf, oldvers)
|
||||||
|
|
||||||
class Options(NamedTuple):
|
class Options(NamedTuple):
|
||||||
ver_files: Optional[Tuple[Path, Path]]
|
ver_files: Optional[Tuple[Path, Path]]
|
||||||
max_concurrency: int
|
max_concurrency: int
|
||||||
|
@ -180,6 +272,7 @@ class Options(NamedTuple):
|
||||||
source_configs: Dict[str, Dict[str, Any]]
|
source_configs: Dict[str, Dict[str, Any]]
|
||||||
httplib: Optional[str]
|
httplib: Optional[str]
|
||||||
http_timeout: int
|
http_timeout: int
|
||||||
|
nix_expr_folder: Optional[Path]
|
||||||
|
|
||||||
def load_file(
|
def load_file(
|
||||||
file: str, *,
|
file: str, *,
|
||||||
|
@ -194,6 +287,7 @@ def load_file(
|
||||||
ver_files: Optional[Tuple[Path, Path]] = None
|
ver_files: Optional[Tuple[Path, Path]] = None
|
||||||
keymanager = KeyManager(None)
|
keymanager = KeyManager(None)
|
||||||
source_configs = {}
|
source_configs = {}
|
||||||
|
nix_expr_folder: Optional[Path] = None
|
||||||
|
|
||||||
if '__config__' in config:
|
if '__config__' in config:
|
||||||
c = config.pop('__config__')
|
c = config.pop('__config__')
|
||||||
|
@ -208,6 +302,11 @@ def load_file(
|
||||||
newver = d / newver_s
|
newver = d / newver_s
|
||||||
ver_files = oldver, newver
|
ver_files = oldver, newver
|
||||||
|
|
||||||
|
if 'nix-expr-folder' in c:
|
||||||
|
nix_expr_s = os.path.expandvars(
|
||||||
|
os.path.expanduser(c.get('nix-expr-folder')))
|
||||||
|
nix_expr_folder = d / nix_expr_s
|
||||||
|
|
||||||
if use_keymanager:
|
if use_keymanager:
|
||||||
keyfile = c.get('keyfile')
|
keyfile = c.get('keyfile')
|
||||||
if keyfile:
|
if keyfile:
|
||||||
|
@ -231,7 +330,7 @@ def load_file(
|
||||||
|
|
||||||
return cast(Entries, config), Options(
|
return cast(Entries, config), Options(
|
||||||
ver_files, max_concurrency, proxy, keymanager,
|
ver_files, max_concurrency, proxy, keymanager,
|
||||||
source_configs, httplib, http_timeout,
|
source_configs, httplib, http_timeout, nix_expr_folder,
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup_httpclient(
|
def setup_httpclient(
|
||||||
|
|
Loading…
Add table
Reference in a new issue