219 lines
6.8 KiB
Python
Executable file
219 lines
6.8 KiB
Python
Executable file
#!/usr/bin/env nix-shell
|
|
#!nix-shell update-luarocks-shell.nix -i python3
|
|
|
|
# format:
|
|
# $ nix run nixpkgs.python3Packages.black -c black update.py
|
|
# type-check:
|
|
# $ nix run nixpkgs.python3Packages.mypy -c mypy update.py
|
|
# linted:
|
|
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265,E402 update.py
|
|
|
|
import inspect
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
from dataclasses import dataclass
|
|
import subprocess
|
|
import csv
|
|
import logging
|
|
import textwrap
|
|
from multiprocessing.dummy import Pool
|
|
|
|
from typing import List, Tuple, Optional
|
|
from pathlib import Path
|
|
|
|
log = logging.getLogger()
|
|
log.addHandler(logging.StreamHandler())
|
|
|
|
ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))).parent.parent # type: ignore
|
|
from pluginupdate import Editor, update_plugins, FetchConfig, CleanEnvironment
|
|
|
|
PKG_LIST="maintainers/scripts/luarocks-packages.csv"
|
|
TMP_FILE="$(mktemp)"
|
|
GENERATED_NIXFILE="pkgs/development/lua-modules/generated-packages.nix"
|
|
LUAROCKS_CONFIG="maintainers/scripts/luarocks-config.lua"
|
|
|
|
HEADER = """/* {GENERATED_NIXFILE} is an auto-generated file -- DO NOT EDIT!
|
|
Regenerate it with:
|
|
nixpkgs$ ./maintainers/scripts/update-luarocks-packages
|
|
|
|
You can customize the generated packages in pkgs/development/lua-modules/overrides.nix
|
|
*/
|
|
""".format(GENERATED_NIXFILE=GENERATED_NIXFILE)
|
|
|
|
FOOTER="""
|
|
}
|
|
/* GENERATED - do not edit this file */
|
|
"""
|
|
|
|
@dataclass
|
|
class LuaPlugin:
|
|
name: str
|
|
'''Name of the plugin, as seen on luarocks.org'''
|
|
src: str
|
|
'''address to the git repository'''
|
|
ref: Optional[str]
|
|
'''git reference (branch name/tag)'''
|
|
version: Optional[str]
|
|
'''Set it to pin a package '''
|
|
server: Optional[str]
|
|
'''luarocks.org registers packages under different manifests.
|
|
Its value can be 'http://luarocks.org/dev'
|
|
'''
|
|
luaversion: Optional[str]
|
|
'''Attribue of the lua interpreter if a package is available only for a specific lua version'''
|
|
maintainers: Optional[str]
|
|
''' Optional string listing maintainers separated by spaces'''
|
|
|
|
@property
|
|
def normalized_name(self) -> str:
|
|
return self.name.replace(".", "-")
|
|
|
|
# rename Editor to LangUpdate/ EcosystemUpdater
|
|
class LuaEditor(Editor):
|
|
def get_current_plugins(self):
|
|
return []
|
|
|
|
def load_plugin_spec(self, input_file) -> List[LuaPlugin]:
|
|
luaPackages = []
|
|
csvfilename=input_file
|
|
log.info("Loading package descriptions from %s", csvfilename)
|
|
|
|
with open(csvfilename, newline='') as csvfile:
|
|
reader = csv.DictReader(csvfile,)
|
|
for row in reader:
|
|
# name,server,version,luaversion,maintainers
|
|
plugin = LuaPlugin(**row)
|
|
luaPackages.append(plugin)
|
|
return luaPackages
|
|
|
|
def generate_nix(
|
|
self,
|
|
results: List[Tuple[LuaPlugin, str]],
|
|
outfilename: str
|
|
):
|
|
|
|
with tempfile.NamedTemporaryFile("w+") as f:
|
|
f.write(HEADER)
|
|
header2 = textwrap.dedent(
|
|
# header2 = inspect.cleandoc(
|
|
"""
|
|
{ self, stdenv, lib, fetchurl, fetchgit, callPackage, ... } @ args:
|
|
final: prev:
|
|
{
|
|
""")
|
|
f.write(header2)
|
|
for (plugin, nix_expr) in results:
|
|
f.write(f"{plugin.normalized_name} = {nix_expr}")
|
|
f.write(FOOTER)
|
|
f.flush()
|
|
|
|
# if everything went fine, move the generated file to its destination
|
|
# using copy since move doesn't work across disks
|
|
shutil.copy(f.name, outfilename)
|
|
|
|
print(f"updated {outfilename}")
|
|
|
|
@property
|
|
def attr_path(self):
|
|
return "luaPackages"
|
|
|
|
def get_update(self, input_file: str, outfile: str, config: FetchConfig):
|
|
_prefetch = generate_pkg_nix
|
|
|
|
def update() -> dict:
|
|
plugin_specs = self.load_plugin_spec(input_file)
|
|
sorted_plugin_specs = sorted(plugin_specs, key=lambda v: v.name.lower())
|
|
|
|
try:
|
|
pool = Pool(processes=config.proc)
|
|
results = pool.map(_prefetch, sorted_plugin_specs)
|
|
finally:
|
|
pass
|
|
|
|
self.generate_nix(results, outfile)
|
|
|
|
redirects = {}
|
|
return redirects
|
|
|
|
return update
|
|
|
|
def rewrite_input(self, input_file: str, *args, **kwargs):
|
|
# vim plugin reads the file before update but that shouldn't be our case
|
|
# not implemented yet
|
|
# fieldnames = ['name', 'server', 'version', 'luaversion', 'maintainers']
|
|
# input_file = "toto.csv"
|
|
# with open(input_file, newline='') as csvfile:
|
|
# writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
|
# writer.writeheader()
|
|
# for row in reader:
|
|
# # name,server,version,luaversion,maintainers
|
|
# plugin = LuaPlugin(**row)
|
|
# luaPackages.append(plugin)
|
|
pass
|
|
|
|
def generate_pkg_nix(plug: LuaPlugin):
|
|
'''
|
|
Generate nix expression for a luarocks package
|
|
Our cache key associates "p.name-p.version" to its rockspec
|
|
'''
|
|
log.debug("Generating nix expression for %s", plug.name)
|
|
custom_env = os.environ.copy()
|
|
custom_env['LUAROCKS_CONFIG'] = LUAROCKS_CONFIG
|
|
|
|
cmd = [ "luarocks", "nix"]
|
|
|
|
if plug.maintainers:
|
|
cmd.append(f"--maintainers={plug.maintainers}")
|
|
|
|
# if plug.server == "src":
|
|
if plug.src != "":
|
|
if plug.src is None:
|
|
msg = "src must be set when 'version' is set to \"src\" for package %s" % plug.name
|
|
log.error(msg)
|
|
raise RuntimeError(msg)
|
|
log.debug("Updating from source %s", plug.src)
|
|
cmd.append(plug.src)
|
|
# update the plugin from luarocks
|
|
else:
|
|
cmd.append(plug.name)
|
|
if plug.version and plug.version != "src":
|
|
|
|
cmd.append(plug.version)
|
|
|
|
if plug.server != "src" and plug.server:
|
|
cmd.append(f"--only-server={plug.server}")
|
|
|
|
if plug.luaversion:
|
|
with CleanEnvironment():
|
|
local_pkgs = str(ROOT.resolve())
|
|
cmd2 = ["nix-build", "--no-out-link", local_pkgs, "-A", f"{plug.luaversion}"]
|
|
|
|
log.debug("running %s", ' '.join(cmd2))
|
|
lua_drv_path=subprocess.check_output(cmd2, text=True).strip()
|
|
cmd.append(f"--lua-dir={lua_drv_path}/bin")
|
|
|
|
log.debug("running %s", ' '.join(cmd))
|
|
|
|
output = subprocess.check_output(cmd, env=custom_env, text=True)
|
|
output = "callPackage(" + output.strip() + ") {};\n\n"
|
|
return (plug, output)
|
|
|
|
def main():
|
|
|
|
editor = LuaEditor("lua", ROOT, '',
|
|
default_in = ROOT.joinpath(PKG_LIST),
|
|
default_out = ROOT.joinpath(GENERATED_NIXFILE)
|
|
)
|
|
|
|
parser = editor.create_parser()
|
|
args = parser.parse_args()
|
|
|
|
update_plugins(editor, args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|
|
|
|
# vim: set ft=python noet fdm=manual fenc=utf-8 ff=unix sts=0 sw=4 ts=4 :
|