about summary refs log tree commit diff
path: root/nixpkgs/maintainers/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/maintainers/scripts')
-rw-r--r--nixpkgs/maintainers/scripts/all-tarballs.nix2
-rwxr-xr-xnixpkgs/maintainers/scripts/fix-maintainers.pl14
-rw-r--r--nixpkgs/maintainers/scripts/luarocks-packages.csv6
-rw-r--r--nixpkgs/maintainers/scripts/pluginupdate.py47
-rwxr-xr-xnixpkgs/maintainers/scripts/sha-to-sri.py228
-rwxr-xr-xnixpkgs/maintainers/scripts/sha256-to-SRI.py149
-rwxr-xr-xnixpkgs/maintainers/scripts/update-luarocks-packages98
7 files changed, 330 insertions, 214 deletions
diff --git a/nixpkgs/maintainers/scripts/all-tarballs.nix b/nixpkgs/maintainers/scripts/all-tarballs.nix
index 6a4de8a4b951..83236e6fa91e 100644
--- a/nixpkgs/maintainers/scripts/all-tarballs.nix
+++ b/nixpkgs/maintainers/scripts/all-tarballs.nix
@@ -12,5 +12,5 @@ import ../../pkgs/top-level/release.nix
     scrubJobs = false;
     # No need to evaluate on i686.
     supportedSystems = [ "x86_64-linux" ];
-    limitedSupportedSystems = [];
+    bootstrapConfigs = [];
   }
diff --git a/nixpkgs/maintainers/scripts/fix-maintainers.pl b/nixpkgs/maintainers/scripts/fix-maintainers.pl
index a83df9ec0cf0..c953cff5cc48 100755
--- a/nixpkgs/maintainers/scripts/fix-maintainers.pl
+++ b/nixpkgs/maintainers/scripts/fix-maintainers.pl
@@ -13,12 +13,15 @@ STDOUT->autoflush(1);
 
 my $ua = LWP::UserAgent->new();
 
+if (!defined $ENV{GH_TOKEN}) {
+    die "Set GH_TOKEN before running this script";
+}
+
 keys %$maintainers_json; # reset the internal iterator so a prior each() doesn't affect the loop
 while(my($k, $v) = each %$maintainers_json) {
     my $current_user = %$v{'github'};
     if (!defined $current_user) {
         print "$k has no github handle\n";
-        next;
     }
     my $github_id = %$v{'githubId'};
     if (!defined $github_id) {
@@ -37,13 +40,16 @@ while(my($k, $v) = each %$maintainers_json) {
         sleep($ratelimit_reset - time() + 5);
     }
     if ($resp->code != 200) {
-        print $current_user . " likely deleted their github account\n";
+        print "$k likely deleted their github account\n";
         next;
     }
     my $resp_json = from_json($resp->content);
     my $api_user = %$resp_json{"login"};
-    if (lc($current_user) ne lc($api_user)) {
-        print $current_user . " is now known on github as " . $api_user . ". Editing maintainer-list.nix…\n";
+    if (!defined $current_user) {
+        print "$k is known on github as $api_user.\n";
+    }
+    elsif (lc($current_user) ne lc($api_user)) {
+        print "$k is now known on github as $api_user. Editing maintainer-list.nix…\n";
         my $file = path($maintainers_list_nix);
         my $data = $file->slurp_utf8;
         $data =~ s/github = "$current_user";$/github = "$api_user";/m;
diff --git a/nixpkgs/maintainers/scripts/luarocks-packages.csv b/nixpkgs/maintainers/scripts/luarocks-packages.csv
index 52ac8a934319..5897948a9f83 100644
--- a/nixpkgs/maintainers/scripts/luarocks-packages.csv
+++ b/nixpkgs/maintainers/scripts/luarocks-packages.csv
@@ -34,7 +34,6 @@ loadkit,,,,,,alerque
 lpeg,,,,,,vyp
 lpeg_patterns,,,,,,
 lpeglabel,,,,1.6.0,,
-lpty,,,,,,
 lrexlib-gnu,,,,,,
 lrexlib-pcre,,,,,,vyp
 lrexlib-posix,,,,,,
@@ -72,6 +71,7 @@ lualogging,,,,,,
 luaossl,,,,,5.1,
 luaposix,,,,34.1.1-1,,vyp lblasc
 luarepl,,,,,,
+luarocks-build-rust-mlua,,,,,,mrcjkb
 luasec,,,,,,flosse
 luasocket,,,,,,
 luasql-sqlite3,,,,,,vyp
@@ -89,8 +89,10 @@ lyaml,,,,,,lblasc
 magick,,,,,,donovanglover
 markdown,,,,,,
 mediator_lua,,,,,,
+middleclass,,,,,,
 mpack,,,,,,
 moonscript,https://github.com/leafo/moonscript.git,dev-1,,,,arobyn
+nui-nvim,,,,,,mrcjkb
 nvim-client,https://github.com/neovim/lua-client.git,,,,,
 nvim-cmp,https://github.com/hrsh7th/nvim-cmp,,,,,
 penlight,https://github.com/lunarmodules/Penlight.git,,,,,alerque
@@ -108,5 +110,7 @@ teal-language-server,,,http://luarocks.org/dev,,,
 telescope.nvim,,,,,5.1,
 telescope-manix,,,,,,
 tl,,,,,,mephistophiles
+toml,,,,,,mrcjkb
+toml-edit,,,,,5.1,mrcjkb
 vstruct,https://github.com/ToxicFrog/vstruct.git,,,,,
 vusted,,,,,,figsoda
diff --git a/nixpkgs/maintainers/scripts/pluginupdate.py b/nixpkgs/maintainers/scripts/pluginupdate.py
index 6a607eb62480..52e9af399709 100644
--- a/nixpkgs/maintainers/scripts/pluginupdate.py
+++ b/nixpkgs/maintainers/scripts/pluginupdate.py
@@ -321,8 +321,13 @@ def load_plugins_from_csv(
     return plugins
 
 
-def run_nix_expr(expr):
-    with CleanEnvironment() as nix_path:
+
+def run_nix_expr(expr, nixpkgs: str):
+    '''
+    :param expr nix expression to fetch current plugins
+    :param nixpkgs Path towards a nixpkgs checkout
+    '''
+    with CleanEnvironment(nixpkgs) as nix_path:
         cmd = [
             "nix",
             "eval",
@@ -335,8 +340,8 @@ def run_nix_expr(expr):
             "--nix-path",
             nix_path,
         ]
-        log.debug("Running command %s", " ".join(cmd))
-        out = subprocess.check_output(cmd)
+        log.debug("Running command: %s", " ".join(cmd))
+        out = subprocess.check_output(cmd, timeout=90)
         data = json.loads(out)
         return data
 
@@ -396,9 +401,9 @@ class Editor:
         """CSV spec"""
         print("the update member function should be overriden in subclasses")
 
-    def get_current_plugins(self) -> List[Plugin]:
+    def get_current_plugins(self, nixpkgs) -> List[Plugin]:
         """To fill the cache"""
-        data = run_nix_expr(self.get_plugins)
+        data = run_nix_expr(self.get_plugins, nixpkgs)
         plugins = []
         for name, attr in data.items():
             p = Plugin(name, attr["rev"], attr["submodules"], attr["sha256"])
@@ -414,7 +419,7 @@ class Editor:
         raise NotImplementedError()
 
     def get_update(self, input_file: str, outfile: str, config: FetchConfig):
-        cache: Cache = Cache(self.get_current_plugins(), self.cache_file)
+        cache: Cache = Cache(self.get_current_plugins(self.nixpkgs), self.cache_file)
         _prefetch = functools.partial(prefetch, cache=cache)
 
         def update() -> dict:
@@ -454,6 +459,12 @@ class Editor:
             ),
         )
         common.add_argument(
+            "--nixpkgs",
+            type=str,
+            default=os.getcwd(),
+            help="Adjust log level",
+        )
+        common.add_argument(
             "--input-names",
             "-i",
             dest="input_file",
@@ -541,22 +552,26 @@ class Editor:
         command = args.command or "update"
         log.setLevel(LOG_LEVELS[args.debug])
         log.info("Chose to run command: %s", command)
+        self.nixpkgs = args.nixpkgs
 
-        if not args.no_commit:
-            self.nixpkgs_repo = git.Repo(self.root, search_parent_directories=True)
+        self.nixpkgs_repo = git.Repo(args.nixpkgs, search_parent_directories=True)
 
         getattr(self, command)(args)
 
 
 class CleanEnvironment(object):
+    def __init__(self, nixpkgs):
+        self.local_pkgs = nixpkgs
+
     def __enter__(self) -> str:
-        self.old_environ = os.environ.copy()
+        """
         local_pkgs = str(Path(__file__).parent.parent.parent)
+        """
+        self.old_environ = os.environ.copy()
         self.empty_config = NamedTemporaryFile()
         self.empty_config.write(b"{}")
         self.empty_config.flush()
-        os.environ["NIXPKGS_CONFIG"] = self.empty_config.name
-        return f"localpkgs={local_pkgs}"
+        return f"localpkgs={self.local_pkgs}"
 
     def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
         os.environ.update(self.old_environ)
@@ -758,7 +773,8 @@ def commit(repo: git.Repo, message: str, files: List[Path]) -> None:
 
 
 def update_plugins(editor: Editor, args):
-    """The main entry function of this module. All input arguments are grouped in the `Editor`."""
+    """The main entry function of this module.
+    All input arguments are grouped in the `Editor`."""
 
     log.info("Start updating plugins")
     fetch_config = FetchConfig(args.proc, args.github_token)
@@ -770,8 +786,11 @@ def update_plugins(editor: Editor, args):
     autocommit = not args.no_commit
 
     if autocommit:
+        from datetime import date
         editor.nixpkgs_repo = git.Repo(editor.root, search_parent_directories=True)
-        commit(editor.nixpkgs_repo, f"{editor.attr_path}: update", [args.outfile])
+        updated = date.today().strftime('%m-%d-%Y')
+
+        commit(editor.nixpkgs_repo, f"{editor.attr_path}: updated the {updated}", [args.outfile])
 
     if redirects:
         update()
diff --git a/nixpkgs/maintainers/scripts/sha-to-sri.py b/nixpkgs/maintainers/scripts/sha-to-sri.py
new file mode 100755
index 000000000000..1af7ff215ad3
--- /dev/null
+++ b/nixpkgs/maintainers/scripts/sha-to-sri.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env nix-shell
+#! nix-shell -i "python3 -I" -p "python3.withPackages(p: with p; [ rich structlog ])"
+
+from abc import ABC, abstractclassmethod, abstractmethod
+from contextlib import contextmanager
+from pathlib import Path
+from structlog.contextvars import bound_contextvars as log_context
+from typing import ClassVar, List, Tuple
+
+import hashlib, re, structlog
+
+
+logger = structlog.getLogger("sha-to-SRI")
+
+
+class Encoding(ABC):
+    alphabet: ClassVar[str]
+
+    @classmethod
+    @property
+    def name(cls) -> str:
+        return cls.__name__.lower()
+
+    def toSRI(self, s: str) -> str:
+        digest = self.decode(s)
+        assert len(digest) == self.n
+
+        from base64 import b64encode
+        return f"{self.hashName}-{b64encode(digest).decode()}"
+
+    @classmethod
+    def all(cls, h) -> 'List[Encoding]':
+        return [ c(h) for c in cls.__subclasses__() ]
+
+    def __init__(self, h):
+        self.n = h.digest_size
+        self.hashName = h.name
+
+    @property
+    @abstractmethod
+    def length(self) -> int:
+        ...
+
+    @property
+    def regex(self) -> str:
+        return f"[{self.alphabet}]{{{self.length}}}"
+
+    @abstractmethod
+    def decode(self, s: str) -> bytes:
+        ...
+
+
+class Nix32(Encoding):
+    alphabet = "0123456789abcdfghijklmnpqrsvwxyz"
+    inverted  = { c: i for i, c in enumerate(alphabet) }
+
+    @property
+    def length(self):
+        return 1 + (8 * self.n) // 5
+    def decode(self, s: str):
+        assert len(s) == self.length
+        out = [ 0 for _ in range(self.n) ]
+        # TODO: Do better than a list of byte-sized ints
+
+        for n, c in enumerate(reversed(s)):
+            digit = self.inverted[c]
+            i, j = divmod(5 * n, 8)
+            out[i] = out[i] | (digit << j) & 0xff
+            rem = digit >> (8 - j)
+            if rem == 0:
+                continue
+            elif i < self.n:
+                out[i+1] = rem
+            else:
+                raise ValueError(f"Invalid nix32 hash: '{s}'")
+
+        return bytes(out)
+
+class Hex(Encoding):
+    alphabet = "0-9A-Fa-f"
+
+    @property
+    def length(self):
+        return 2 * self.n
+    def decode(self, s: str):
+        from binascii import unhexlify
+        return unhexlify(s)
+
+class Base64(Encoding):
+    alphabet = "A-Za-z0-9+/"
+
+    @property
+    def format(self) -> Tuple[int, int]:
+        """Number of characters in data and padding."""
+        i, k = divmod(self.n, 3)
+        return 4 * i + (0 if k == 0 else k + 1), (3 - k) % 3
+    @property
+    def length(self):
+        return sum(self.format)
+    @property
+    def regex(self):
+        data, padding = self.format
+        return f"[{self.alphabet}]{{{data}}}={{{padding}}}"
+    def decode(self, s):
+        from base64 import b64decode
+        return b64decode(s, validate = True)
+
+
+_HASHES = (hashlib.new(n) for n in ('SHA-256', 'SHA-512'))
+ENCODINGS = {
+    h.name: Encoding.all(h)
+    for h in _HASHES
+}
+
+RE = {
+    h: "|".join(
+        (f"({h}-)?" if e.name == 'base64' else '') +
+        f"(?P<{h}_{e.name}>{e.regex})"
+        for e in encodings
+    ) for h, encodings in ENCODINGS.items()
+}
+
+_DEF_RE = re.compile("|".join(
+    f"(?P<{h}>{h} = (?P<{h}_quote>['\"])({re})(?P={h}_quote);)"
+    for h, re in RE.items()
+))
+
+
+def defToSRI(s: str) -> str:
+    def f(m: re.Match[str]) -> str:
+        try:
+            for h, encodings in ENCODINGS.items():
+                if m.group(h) is None:
+                    continue
+
+                for e in encodings:
+                    s = m.group(f"{h}_{e.name}")
+                    if s is not None:
+                        return f'hash = "{e.toSRI(s)}";'
+
+                raise ValueError(f"Match with '{h}' but no subgroup")
+            raise ValueError("Match with no hash")
+
+        except ValueError as exn:
+            logger.error(
+                "Skipping",
+                exc_info = exn,
+            )
+            return m.group()
+
+    return _DEF_RE.sub(f, s)
+
+
+@contextmanager
+def atomicFileUpdate(target: Path):
+    '''Atomically replace the contents of a file.
+
+    Guarantees that no temporary files are left behind, and `target` is either
+    left untouched, or overwritten with new content if no exception was raised.
+
+    Yields a pair `(original, new)` of open files.
+    `original` is the pre-existing file at `target`, open for reading;
+    `new` is an empty, temporary file in the same filder, open for writing.
+
+    Upon exiting the context, the files are closed; if no exception was
+    raised, `new` (atomically) replaces the `target`, otherwise it is deleted.
+    '''
+    # That's mostly copied from noto-emoji.py, should DRY it out
+    from tempfile import mkstemp
+    fd, _p = mkstemp(
+        dir = target.parent,
+        prefix = target.name,
+    )
+    tmpPath = Path(_p)
+
+    try:
+        with target.open() as original:
+            with tmpPath.open('w') as new:
+                yield (original, new)
+
+        tmpPath.replace(target)
+
+    except Exception:
+        tmpPath.unlink(missing_ok = True)
+        raise
+
+
+def fileToSRI(p: Path):
+    with atomicFileUpdate(p) as (og, new):
+        for i, line in enumerate(og):
+            with log_context(line=i):
+                new.write(defToSRI(line))
+
+
+_SKIP_RE = re.compile(
+    "(generated by)|(do not edit)",
+    re.IGNORECASE
+)
+
+if __name__ == "__main__":
+    from sys import argv, stderr
+    logger.info("Starting!")
+
+    for arg in argv[1:]:
+        p = Path(arg)
+        with log_context(path=str(p)):
+            try:
+                if p.name == "yarn.nix" or p.name.find("generated") != -1:
+                    logger.warning("File looks autogenerated, skipping!")
+                    continue
+
+                with p.open() as f:
+                    for line in f:
+                        if line.strip():
+                            break
+
+                    if _SKIP_RE.search(line):
+                        logger.warning("File looks autogenerated, skipping!")
+                        continue
+
+                fileToSRI(p)
+            except Exception as exn:
+                logger.error(
+                    "Unhandled exception, skipping file!",
+                    exc_info = exn,
+                )
+            else:
+                logger.info("Finished processing file")
diff --git a/nixpkgs/maintainers/scripts/sha256-to-SRI.py b/nixpkgs/maintainers/scripts/sha256-to-SRI.py
deleted file mode 100755
index dcacb4c58044..000000000000
--- a/nixpkgs/maintainers/scripts/sha256-to-SRI.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env nix-shell
-#! nix-shell -i "python3 -I" -p "python3.withPackages(p: with p; [ rich structlog ])"
-
-from contextlib import contextmanager
-from pathlib import Path
-from structlog.contextvars import bound_contextvars as log_context
-
-import re, structlog
-
-
-logger = structlog.getLogger("sha256-to-SRI")
-
-
-nix32alphabet = "0123456789abcdfghijklmnpqrsvwxyz"
-nix32inverted  = { c: i for i, c in enumerate(nix32alphabet) }
-
-def nix32decode(s: str) -> bytes:
-    # only support sha256 hashes for now
-    assert len(s) == 52
-    out = [ 0 for _ in range(32) ]
-    # TODO: Do better than a list of byte-sized ints
-
-    for n, c in enumerate(reversed(s)):
-        digit = nix32inverted[c]
-        i, j = divmod(5 * n, 8)
-        out[i] = out[i] | (digit << j) & 0xff
-        rem = digit >> (8 - j)
-        if rem == 0:
-            continue
-        elif i < 31:
-            out[i+1] = rem
-        else:
-            raise ValueError(f"Invalid nix32 hash: '{s}'")
-
-    return bytes(out)
-
-
-def toSRI(digest: bytes) -> str:
-    from base64 import b64encode
-    assert len(digest) == 32
-    return f"sha256-{b64encode(digest).decode()}"
-
-
-RE = {
-    'nix32': f"[{nix32alphabet}]" "{52}",
-    'hex':    "[0-9A-Fa-f]{64}",
-    'base64': "[A-Za-z0-9+/]{43}=",
-}
-RE['sha256'] = '|'.join(
-    f"{'(sha256-)?' if name == 'base64' else ''}"
-    f"(?P<{name}>{r})"
-    for name, r in RE.items()
-)
-
-def sha256toSRI(m: re.Match) -> str:
-    """Produce the equivalent SRI string for any match of RE['sha256']"""
-    if m['nix32'] is not None:
-        return toSRI(nix32decode(m['nix32']))
-    if m['hex'] is not None:
-        from binascii import unhexlify
-        return toSRI(unhexlify(m['hex']))
-    if m['base64'] is not None:
-        from base64 import b64decode
-        return toSRI(b64decode(m['base64']))
-
-    raise ValueError("Got a match where none of the groups captured")
-
-
-# Ohno I used evil, irregular backrefs instead of making 2 variants  ^^'
-_def_re = re.compile(
-    "sha256 = (?P<quote>[\"'])"
-    f"({RE['sha256']})"
-    "(?P=quote);"
-)
-
-def defToSRI(s: str) -> str:
-    def f(m: re.Match[str]) -> str:
-        try:
-            return f'hash = "{sha256toSRI(m)}";'
-
-        except ValueError as exn:
-            begin, end = m.span()
-            match = m.string[begin:end]
-
-            logger.error(
-                "Skipping",
-                exc_info = exn,
-            )
-            return match
-
-    return _def_re.sub(f, s)
-
-
-@contextmanager
-def atomicFileUpdate(target: Path):
-    '''Atomically replace the contents of a file.
-
-    Guarantees that no temporary files are left behind, and `target` is either
-    left untouched, or overwritten with new content if no exception was raised.
-
-    Yields a pair `(original, new)` of open files.
-    `original` is the pre-existing file at `target`, open for reading;
-    `new` is an empty, temporary file in the same filder, open for writing.
-
-    Upon exiting the context, the files are closed; if no exception was
-    raised, `new` (atomically) replaces the `target`, otherwise it is deleted.
-    '''
-    # That's mostly copied from noto-emoji.py, should DRY it out
-    from tempfile import mkstemp
-    fd, _p = mkstemp(
-        dir = target.parent,
-        prefix = target.name,
-    )
-    tmpPath = Path(_p)
-
-    try:
-        with target.open() as original:
-            with tmpPath.open('w') as new:
-                yield (original, new)
-
-        tmpPath.replace(target)
-
-    except Exception:
-        tmpPath.unlink(missing_ok = True)
-        raise
-
-
-def fileToSRI(p: Path):
-    with atomicFileUpdate(p) as (og, new):
-        for i, line in enumerate(og):
-            with log_context(line=i):
-                new.write(defToSRI(line))
-
-
-if __name__ == "__main__":
-    from sys import argv, stderr
-
-    for arg in argv[1:]:
-        p = Path(arg)
-        with log_context(path=str(p)):
-            try:
-                fileToSRI(p)
-            except Exception as exn:
-                logger.error(
-                    "Unhandled exception, skipping file!",
-                    exc_info = exn,
-                )
-            else:
-                logger.info("Finished processing file")
diff --git a/nixpkgs/maintainers/scripts/update-luarocks-packages b/nixpkgs/maintainers/scripts/update-luarocks-packages
index 791cd8a1d89d..32c2b44260b3 100755
--- a/nixpkgs/maintainers/scripts/update-luarocks-packages
+++ b/nixpkgs/maintainers/scripts/update-luarocks-packages
@@ -2,11 +2,11 @@
 #!nix-shell update-luarocks-shell.nix -i python3
 
 # format:
-# $ nix run nixpkgs.python3Packages.black -c black update.py
+# $ nix run nixpkgs#python3Packages.black -- update.py
 # type-check:
-# $ nix run nixpkgs.python3Packages.mypy -c mypy update.py
+# $ nix run nixpkgs#python3Packages.mypy -- update.py
 # linted:
-# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265,E402 update.py
+# $ nix run nixpkgs#python3Packages.flake8 -- --ignore E501,E265,E402 update.py
 
 import inspect
 import os
@@ -25,14 +25,14 @@ 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
+ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))).parent.parent  # type: ignore
 import pluginupdate
 from pluginupdate import 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"
+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:
@@ -40,36 +40,40 @@ nixpkgs$ ./maintainers/scripts/update-luarocks-packages
 
 You can customize the generated packages in pkgs/development/lua-modules/overrides.nix
 */
-""".format(GENERATED_NIXFILE=GENERATED_NIXFILE)
+""".format(
+    GENERATED_NIXFILE=GENERATED_NIXFILE
+)
 
-FOOTER="""
+FOOTER = """
 }
 /* GENERATED - do not edit this file */
 """
 
+
 @dataclass
 class LuaPlugin:
     name: str
-    '''Name of the plugin, as seen on luarocks.org'''
+    """Name of the plugin, as seen on luarocks.org"""
     src: str
-    '''address to the git repository'''
+    """address to the git repository"""
     ref: Optional[str]
-    '''git reference (branch name/tag)'''
+    """git reference (branch name/tag)"""
     version: Optional[str]
-    '''Set it to pin a package '''
+    """Set it to pin a package """
     server: Optional[str]
-    '''luarocks.org registers packages under different manifests.
+    """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'''
+    """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'''
+    """ Optional string listing maintainers separated by spaces"""
 
     @property
     def normalized_name(self) -> str:
         return self.name.replace(".", "-")
 
+
 # rename Editor to LangUpdate/ EcosystemUpdater
 class LuaEditor(pluginupdate.Editor):
     def get_current_plugins(self):
@@ -77,11 +81,13 @@ class LuaEditor(pluginupdate.Editor):
 
     def load_plugin_spec(self, input_file) -> List[LuaPlugin]:
         luaPackages = []
-        csvfilename=input_file
+        csvfilename = input_file
         log.info("Loading package descriptions from %s", csvfilename)
 
-        with open(csvfilename, newline='') as csvfile:
-            reader = csv.DictReader(csvfile,)
+        with open(csvfilename, newline="") as csvfile:
+            reader = csv.DictReader(
+                csvfile,
+            )
             for row in reader:
                 # name,server,version,luaversion,maintainers
                 plugin = LuaPlugin(**row)
@@ -91,23 +97,19 @@ class LuaEditor(pluginupdate.Editor):
     def update(self, args):
         update_plugins(self, args)
 
-    def generate_nix(
-        self,
-        results: List[Tuple[LuaPlugin, str]],
-        outfilename: str
-        ):
-
+    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(
-            """
+                # header2 = inspect.cleandoc(
+                """
                 { self, stdenv, lib, fetchurl, fetchgit, callPackage, ... } @ args:
                 final: prev:
                 {
-            """)
+            """
+            )
             f.write(header2)
-            for (plugin, nix_expr) in results:
+            for plugin, nix_expr in results:
                 f.write(f"{plugin.normalized_name} = {nix_expr}")
             f.write(FOOTER)
             f.flush()
@@ -156,19 +158,20 @@ class LuaEditor(pluginupdate.Editor):
         #         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
+    custom_env["LUAROCKS_CONFIG"] = LUAROCKS_CONFIG
 
     # we add --dev else luarocks wont find all the "scm" (=dev) versions of the
     # packages
-	# , "--dev"
-    cmd = [ "luarocks", "nix" ]
+    # , "--dev"
+    cmd = ["luarocks", "nix"]
 
     if plug.maintainers:
         cmd.append(f"--maintainers={plug.maintainers}")
@@ -176,7 +179,10 @@ def generate_pkg_nix(plug: LuaPlugin):
     # 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
+            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)
@@ -185,7 +191,6 @@ def generate_pkg_nix(plug: LuaPlugin):
     else:
         cmd.append(plug.name)
         if plug.version and plug.version != "src":
-
             cmd.append(plug.version)
 
     if plug.server != "src" and plug.server:
@@ -194,23 +199,26 @@ def generate_pkg_nix(plug: LuaPlugin):
     if plug.luaversion:
         cmd.append(f"--lua-version={plug.luaversion}")
 
-    log.debug("running %s", ' '.join(cmd))
+    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)
-        )
+def main():
+    editor = LuaEditor(
+        "lua",
+        ROOT,
+        "",
+        default_in=ROOT.joinpath(PKG_LIST),
+        default_out=ROOT.joinpath(GENERATED_NIXFILE),
+    )
 
     editor.run()
 
-if __name__ == "__main__":
 
+if __name__ == "__main__":
     main()
 
 #  vim: set ft=python noet fdm=manual fenc=utf-8 ff=unix sts=0 sw=4 ts=4 :