Merge master into staging-next

This commit is contained in:
github-actions[bot] 2023-09-30 12:01:05 +00:00 committed by GitHub
commit c3098253b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 206 additions and 118 deletions

View File

@ -178,6 +178,12 @@ rec {
else if final.isLoongArch64 then "loongarch"
else final.parsed.cpu.name;
# https://source.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L81-106
ubootArch =
if final.isx86_32 then "x86" # not i386
else if final.isMips64 then "mips64" # uboot *does* distinguish between mips32/mips64
else final.linuxArch; # other cases appear to agree with linuxArch
qemuArch =
if final.isAarch32 then "arm"
else if final.isS390 && !final.isS390x then null

View File

@ -17720,6 +17720,13 @@
githubId = 25440339;
name = "Tom Repetti";
};
trevdev = {
email = "trev@trevdev.ca";
matrix = "@trevdev:matrix.org";
github = "trev-dev";
githubId = 28788713;
name = "Trevor Richards";
};
trevorj = {
email = "nix@trevor.joynson.io";
github = "akatrevorjay";

View File

@ -4,19 +4,20 @@
, qemu_pkg ? qemu_test
, coreutils
, imagemagick_light
, libtiff
, netpbm
, qemu_test
, socat
, ruff
, tesseract4
, vde2
, extraPythonPackages ? (_ : [])
}:
python3Packages.buildPythonApplication rec {
python3Packages.buildPythonApplication {
pname = "nixos-test-driver";
version = "1.1";
src = ./.;
format = "pyproject";
propagatedBuildInputs = [
coreutils
@ -31,14 +32,13 @@ python3Packages.buildPythonApplication rec {
++ extraPythonPackages python3Packages;
doCheck = true;
nativeCheckInputs = with python3Packages; [ mypy pylint black ];
nativeCheckInputs = with python3Packages; [ mypy ruff black ];
checkPhase = ''
mypy --disallow-untyped-defs \
--no-implicit-optional \
--pretty \
--no-color-output \
--ignore-missing-imports ${src}/test_driver
pylint --errors-only --enable=unused-import ${src}/test_driver
black --check --diff ${src}/test_driver
echo -e "\x1b[32m## run mypy\x1b[0m"
mypy test_driver extract-docstrings.py
echo -e "\x1b[32m## run ruff\x1b[0m"
ruff .
echo -e "\x1b[32m## run black\x1b[0m"
black --check --diff .
'';
}

View File

@ -1,5 +1,6 @@
import ast
import sys
from pathlib import Path
"""
This program takes all the Machine class methods and prints its methods in
@ -40,27 +41,34 @@ some_function(param1, param2)
"""
assert len(sys.argv) == 2
with open(sys.argv[1], "r") as f:
module = ast.parse(f.read())
def main() -> None:
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <path-to-test-driver>")
sys.exit(1)
class_definitions = (node for node in module.body if isinstance(node, ast.ClassDef))
module = ast.parse(Path(sys.argv[1]).read_text())
machine_class = next(filter(lambda x: x.name == "Machine", class_definitions))
assert machine_class is not None
class_definitions = (node for node in module.body if isinstance(node, ast.ClassDef))
function_definitions = [
node for node in machine_class.body if isinstance(node, ast.FunctionDef)
]
function_definitions.sort(key=lambda x: x.name)
machine_class = next(filter(lambda x: x.name == "Machine", class_definitions))
assert machine_class is not None
for f in function_definitions:
docstr = ast.get_docstring(f)
if docstr is not None:
args = ", ".join((a.arg for a in f.args.args[1:]))
args = f"({args})"
function_definitions = [
node for node in machine_class.body if isinstance(node, ast.FunctionDef)
]
function_definitions.sort(key=lambda x: x.name)
docstr = "\n".join((f" {l}" for l in docstr.strip().splitlines()))
for function in function_definitions:
docstr = ast.get_docstring(function)
if docstr is not None:
args = ", ".join(a.arg for a in function.args.args[1:])
args = f"({args})"
print(f"{f.name}{args}\n\n:{docstr[1:]}\n")
docstr = "\n".join(f" {line}" for line in docstr.strip().splitlines())
print(f"{function.name}{args}\n\n:{docstr[1:]}\n")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,44 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "nixos-test-driver"
version = "0.0.0"
[project.scripts]
nixos-test-driver = "test_driver:main"
generate-driver-symbols = "test_driver:generate_driver_symbols"
[tool.setuptools.packages]
find = {}
[tool.setuptools.package-data]
test_driver = ["py.typed"]
[tool.ruff]
line-length = 88
select = ["E", "F", "I", "U", "N"]
ignore = ["E501"]
# xxx: we can import https://pypi.org/project/types-colorama/ here
[[tool.mypy.overrides]]
module = "colorama.*"
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = "ptpython.*"
ignore_missing_imports = true
[tool.black]
line-length = 88
target-version = ['py39']
include = '\.pyi?$'
[tool.mypy]
python_version = "3.10"
warn_redundant_casts = true
disallow_untyped_calls = true
disallow_untyped_defs = true
no_implicit_optional = true

View File

@ -1,14 +0,0 @@
from setuptools import setup, find_packages
setup(
name="nixos-test-driver",
version='1.1',
packages=find_packages(),
package_data={"test_driver": ["py.typed"]},
entry_points={
"console_scripts": [
"nixos-test-driver=test_driver:main",
"generate-driver-symbols=test_driver:generate_driver_symbols"
]
},
)

View File

@ -0,0 +1,2 @@
with import ../../.. {};
pkgs.callPackage ./default.nix {}

View File

@ -1,11 +1,12 @@
from pathlib import Path
import argparse
import ptpython.repl
import os
import time
from pathlib import Path
import ptpython.repl
from test_driver.logger import rootlog
from test_driver.driver import Driver
from test_driver.logger import rootlog
class EnvDefault(argparse.Action):
@ -25,9 +26,7 @@ class EnvDefault(argparse.Action):
)
if required and default:
required = False
super(EnvDefault, self).__init__(
default=default, required=required, nargs=nargs, **kwargs
)
super().__init__(default=default, required=required, nargs=nargs, **kwargs)
def __call__(self, parser, namespace, values, option_string=None): # type: ignore
setattr(namespace, self.dest, values)

View File

@ -1,14 +1,14 @@
from contextlib import contextmanager
from pathlib import Path
from typing import Any, Dict, Iterator, List, Union, Optional, Callable, ContextManager
import os
import re
import tempfile
from contextlib import contextmanager
from pathlib import Path
from typing import Any, Callable, ContextManager, Dict, Iterator, List, Optional, Union
from test_driver.logger import rootlog
from test_driver.machine import Machine, NixStartScript, retry
from test_driver.vlan import VLan
from test_driver.polling_condition import PollingCondition
from test_driver.vlan import VLan
def get_tmp_dir() -> Path:

View File

@ -1,13 +1,17 @@
from colorama import Style, Fore
from contextlib import contextmanager
from typing import Any, Dict, Iterator
from queue import Queue, Empty
from xml.sax.saxutils import XMLGenerator
# mypy: disable-error-code="no-untyped-call"
# drop the above line when mypy is upgraded to include
# https://github.com/python/typeshed/commit/49b717ca52bf0781a538b04c0d76a5513f7119b8
import codecs
import os
import sys
import time
import unicodedata
from contextlib import contextmanager
from queue import Empty, Queue
from typing import Any, Dict, Iterator
from xml.sax.saxutils import XMLGenerator
from colorama import Fore, Style
class Logger:

View File

@ -1,7 +1,3 @@
from contextlib import _GeneratorContextManager, nullcontext
from pathlib import Path
from queue import Queue
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
import base64
import io
import os
@ -16,6 +12,10 @@ import sys
import tempfile
import threading
import time
from contextlib import _GeneratorContextManager, nullcontext
from pathlib import Path
from queue import Queue
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
from test_driver.logger import rootlog
@ -236,14 +236,14 @@ class LegacyStartCommand(StartCommand):
def __init__(
self,
netBackendArgs: Optional[str] = None,
netFrontendArgs: Optional[str] = None,
netBackendArgs: Optional[str] = None, # noqa: N803
netFrontendArgs: Optional[str] = None, # noqa: N803
hda: Optional[Tuple[Path, str]] = None,
cdrom: Optional[str] = None,
usb: Optional[str] = None,
bios: Optional[str] = None,
qemuBinary: Optional[str] = None,
qemuFlags: Optional[str] = None,
qemuBinary: Optional[str] = None, # noqa: N803
qemuFlags: Optional[str] = None, # noqa: N803
):
if qemuBinary is not None:
self._cmd = qemuBinary
@ -599,7 +599,7 @@ class Machine:
return (-1, output.decode())
# Get the return code
self.shell.send("echo ${PIPESTATUS[0]}\n".encode())
self.shell.send(b"echo ${PIPESTATUS[0]}\n")
rc = int(self._next_newline_closed_block_from_shell().strip())
return (rc, output.decode(errors="replace"))
@ -1132,7 +1132,7 @@ class Machine:
return
assert self.shell
self.shell.send("poweroff\n".encode())
self.shell.send(b"poweroff\n")
self.wait_for_shutdown()
def crash(self) -> None:

View File

@ -1,11 +1,11 @@
from typing import Callable, Optional
from math import isfinite
import time
from math import isfinite
from typing import Callable, Optional
from .logger import rootlog
class PollingConditionFailed(Exception):
class PollingConditionError(Exception):
pass
@ -60,7 +60,7 @@ class PollingCondition:
def maybe_raise(self) -> None:
if not self.check():
raise PollingConditionFailed(self.status_message(False))
raise PollingConditionError(self.status_message(False))
def status_message(self, status: bool) -> str:
return f"Polling condition {'succeeded' if status else 'failed'}: {self.description}"

View File

@ -1,8 +1,8 @@
from pathlib import Path
import io
import os
import pty
import subprocess
from pathlib import Path
from test_driver.logger import rootlog

View File

@ -177,6 +177,7 @@ rec {
genJqSecretsReplacementSnippet' = attr: set: output:
let
secrets = recursiveGetAttrWithJqPrefix set attr;
stringOrDefault = str: def: if str == "" then def else str;
in ''
if [[ -h '${output}' ]]; then
rm '${output}'
@ -195,10 +196,12 @@ rec {
(attrNames secrets))
+ "\n"
+ "${pkgs.jq}/bin/jq >'${output}' "
+ lib.escapeShellArg (concatStringsSep
" | "
(imap1 (index: name: ''${name} = $ENV.secret${toString index}'')
(attrNames secrets)))
+ lib.escapeShellArg (stringOrDefault
(concatStringsSep
" | "
(imap1 (index: name: ''${name} = $ENV.secret${toString index}'')
(attrNames secrets)))
".")
+ ''
<<'EOF'
${builtins.toJSON set}

View File

@ -1,4 +1,4 @@
{ mkDerivation, lib, stdenv, makeWrapper, fetchurl, cmake, extra-cmake-modules
{ mkDerivation, lib, stdenv, fetchpatch, makeWrapper, fetchurl, cmake, extra-cmake-modules
, karchive, kconfig, kwidgetsaddons, kcompletion, kcoreaddons
, kguiaddons, ki18n, kitemmodels, kitemviews, kwindowsystem
, kio, kcrash, breeze-icons
@ -21,6 +21,14 @@ mkDerivation rec {
inherit sha256;
};
patches = [
(fetchpatch {
name = "exiv2-0.28.patch";
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/krita/-/raw/acd9a818660e86b14a66fceac295c2bab318c671/exiv2-0.28.patch";
hash = "sha256-iD2pyid513ThJVeotUlVDrwYANofnEiZmWINNUm/saw=";
})
];
nativeBuildInputs = [ cmake extra-cmake-modules python3Packages.sip makeWrapper ];
buildInputs = [

View File

@ -54,7 +54,7 @@ in
# guess may not align with u-boot's nomenclature correctly, so it can
# be overridden.
# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L81-106 for a list.
, uInitrdArch ? stdenvNoCC.hostPlatform.linuxArch
, uInitrdArch ? stdenvNoCC.hostPlatform.ubootArch
# The name of the compression, as recognised by u-boot.
# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L195-204 for a list.

View File

@ -0,0 +1,19 @@
{ lib, pkgs, buildNimPackage, fetchFromGitHub }:
buildNimPackage (finalAttrs: {
pname = "csvtools";
version = "0.2.1";
src = fetchFromGitHub {
owner = "andreaferretti";
repo = "csvtools";
rev = "${finalAttrs.version}";
hash = "sha256-G/OvcusnlRR5zdGF+wC7z411RLXI6D9aFJVj9LrMR+s=";
};
doCheck = true;
meta = finalAttrs.src.meta // {
description = "Manage CSV files easily in Nim";
homepage = "https://github.com/andreaferretti/csvtools";
license = lib.licenses.asl20;
maintainers = [ lib.maintainers.trevdev ];
};
})

View File

@ -142,13 +142,13 @@ rec {
headers = "03mb1v5xzn2lp317r0mik9dx2nnxc7m26imygk13dgmafydd6aah";
};
electron_22-bin = mkElectron "22.3.24" {
armv7l-linux = "bf986ec2e04c1f81a753dc17d71d231e16e0903d9114b1a73b1df0f18281d549";
aarch64-linux = "055776ed281fa2db76a9e663677155b9631e4c6ac57c1e86938c789913c72fe7";
x86_64-linux = "0c48912ff2bcbfe7e7c80eae76b82e2ba1e03cc872c0c6817faa560155447edd";
x86_64-darwin = "a2adc99b44fbded082cbb5f1c49eceaf0c6f678c5ba951332b2c902b4fa7f63e";
aarch64-darwin = "2ac36fdd664cb53c6cbc8ac67ac66e95e6418db4009636fbb865df97b711c818";
headers = "1817viv29v1lgph9rcknm6rz64x6w2l8p0ng681644cv4m5gjsq1";
electron_22-bin = mkElectron "22.3.25" {
armv7l-linux = "d90184e22f9d57fa4f207d5e5006bbfb6df1b9e10760333c3f72353ffa5ef3d1";
aarch64-linux = "08c4e127d06d73ad91fa308c811ace9d4f8607fe15ba0b2694261d32a2127a8c";
x86_64-linux = "f1d0f66b13d5b7b9e3f7d9b22891bf0b5b6f87e45c46054cd3fa74636c19e921";
x86_64-darwin = "945839af7ad0656d6c3462f6b47d871ce3d3860c112b2f574f62624b5b67ca8a";
aarch64-darwin = "3b0d7cb9ca7dda2b178af0084814f82c331df6abac63f19c3c6d72759db1e826";
headers = "0dbwdfrrd3r2kkfq000gwx5q0w01ndgpglkjw7i2q8b3pr5b2n62";
};
electron_23-bin = mkElectron "23.3.13" {
@ -160,30 +160,30 @@ rec {
headers = "04k25z0d6xs2ar5mbbnr0phcs97kvxg28df3njhaniws6wf6qcmg";
};
electron_24-bin = mkElectron "24.8.3" {
armv7l-linux = "93dc26ce72b2b4cafaf1c09091c23c764294a95da040b515963c5a269fc4112a";
aarch64-linux = "6684c37e427335818db146bb7b9c860be72ea582064fad349a54c62042676439";
x86_64-linux = "fcc2754fecdc6ffb814938ae7c806c8ab7d68c748d5906ae3e4b0f3d90eda2e1";
x86_64-darwin = "73f1913a9594057a47d473ff697c36ebb3d7d2fa012a24d301624af15fe9f251";
aarch64-darwin = "1b276595078b2733c33570a0d27309117711d176629580c09bd31e5e3edb21f2";
headers = "1rd0nww6gxvdzw6ja17gv5kd0wszjs9bcfspkp0iamsp5d9ixjf8";
electron_24-bin = mkElectron "24.8.5" {
armv7l-linux = "12063cec367c7ec5b018eb308aaf34cfc73997f325cd37d19703caba842520e2";
aarch64-linux = "a36978af2296a9594035a8dd59c1f7199c68f3f530013a919fc10baec7471668";
x86_64-linux = "bdb2ecc81462018a69f105eb0d121deff48b54831af31b7da664fc193969f352";
x86_64-darwin = "5eb6f9f9f1860bb76267c85b0bc12cc0bd6158b3cc88a2b484e4896e80f6f693";
aarch64-darwin = "49f8a31e3863496d009740ecb4ce95c08870874c284de7a13e8d12c6056c1c48";
headers = "11909wjni9wvlinvp0d7gypmv4sqg7xv0bn5x2x8h4sfgqydzwr6";
};
electron_25-bin = mkElectron "25.8.1" {
armv7l-linux = "dd3390de2426a1cea9d3176e404b8fb250844a9b0e48cf01822fa66f3c3c4a48";
aarch64-linux = "931208419f859f528e19805ae14b5b075213bc40dd20da9e03d8b71d849c147d";
x86_64-linux = "de556aef0a80a8fe7b2b39d74ab0bdecc65d72bba3b7349460d18ef2a22fa323";
x86_64-darwin = "fe61a3221d4c5dc9415dc2cce81010db61bb4a5ab5021d1023f48786dbaf0b28";
aarch64-darwin = "985f4beee009ef6dbe7af75009a1b281aff591b989ee544bd4d2c814f9c4428d";
headers = "1kkkxida3cbril65lmm0lkps787mhrrylzvp0j35rc1ip32b7sda";
electron_25-bin = mkElectron "25.8.4" {
armv7l-linux = "6301e6fde3e7c8149a5eca84c3817ba9ad3ffcb72e79318a355f025d7d3f8408";
aarch64-linux = "fbb6e06417b1741b94d59a6de5dcf3262bfb3fc98cffbcad475296c42d1cbe94";
x86_64-linux = "0cbbcaf90f3dc79dedec97d073ffe954530316523479c31b11781a141f8a87f6";
x86_64-darwin = "d4015cd251e58ef074d1f7f3e99bfbbe4cd6b690981f376fc642b2de955e8750";
aarch64-darwin = "5d83e2094a26bfe22e4c80e660ab088ec94ae3cc2d518c6efcac338f48cc0266";
headers = "10nbnjkmry1dn103jpc3p3jijq8l6zh3cm6k5fqk94nrbmjjdah9";
};
electron_26-bin = mkElectron "26.2.1" {
armv7l-linux = "27469331e1b19f732f67e4b3ae01bba527b2744e31efec1ef76748c45fe7f262";
aarch64-linux = "fe634b9095120d5b5d2c389ca016c378d1c3ba4f49b33912f9a6d8eb46f76163";
x86_64-linux = "be4ca43f4dbc82cacb4c48a04f3c4589fd560a80a77dbb9bdf6c81721c0064df";
x86_64-darwin = "007413187793c94cd248f52d3e00e2d95ed73b7a3b2c5a618f22eba7af94cd1a";
aarch64-darwin = "4e095994525a0e97e897aad9c1940c8160ce2c9aaf7b6792f31720abc3e04ee6";
headers = "02z604nzcm8iw29s5lsgjlzwn666h3ikxpdfjg2h0mffm82d0wfk";
electron_26-bin = mkElectron "26.2.4" {
armv7l-linux = "300e1a3e84d81277f9ab7f5060b980b2b1387979d6f07ea9d78bce5139430420";
aarch64-linux = "a401d68820d1c87006b683d98cfb691ffac1218c815757a3c5a0a4c2f3f08888";
x86_64-linux = "d2226ee3fb8bcd17abfe9747ba6c8d6ae2719a6256896d4861e3cb670ec2beeb";
x86_64-darwin = "a1e33c66a13913306e80812a9051ce7e5632d7cc13ff76910cc8daa791580589";
aarch64-darwin = "dda224e19ff2d2c99624e1da7d20fa24b92a34b49fac8dcef15542e183bc89c6";
headers = "0019pwm7n8vwhdflh1yy0lrgfgg92p9l40iw4xxnhm6ppic1f5kk";
};
}

View File

@ -9,13 +9,13 @@
buildDotnetModule rec {
pname = "jackett";
version = "0.21.932";
version = "0.21.938";
src = fetchFromGitHub {
owner = pname;
repo = pname;
rev = "v${version}";
hash = "sha512-aGuaOLx43P2GzH1BYhLYd9wkkEhuDBH7bdtXlC2kgxcS5GCbn8pVro4VYVxkzh1P3WxpkMoD8A5bDPCHBebX4w==";
hash = "sha512-NxtXVEh56aed7rz4LZZ/pAiB2KHsONfsDXCZzVep60w08rTC+cIbbB5DQcRRdGJk+f6pH35TxcAGuS2nQi+pwg==";
};
projectFile = "src/Jackett.Server/Jackett.Server.csproj";

View File

@ -9,14 +9,14 @@
python3.pkgs.buildPythonApplication rec {
pname = "nix-update";
version = "0.19.3";
version = "1.0.0";
pyproject = true;
src = fetchFromGitHub {
owner = "Mic92";
repo = pname;
rev = version;
hash = "sha256-+WD+SV/L3TvksWBIg6jk+T0dUTNdp4VKONzdzVT+pac=";
hash = "sha256-C7ke51QlBcTR98ovQi5NcxToEPP6s9gqnxWO1eBw/sI=";
};
nativeBuildInputs = [

View File

@ -2,7 +2,7 @@
stdenv.mkDerivation rec {
pname = "vault-bin";
version = "1.14.3";
version = "1.15.0";
src =
let
@ -16,11 +16,11 @@ stdenv.mkDerivation rec {
aarch64-darwin = "darwin_arm64";
};
sha256 = selectSystem {
x86_64-linux = "sha256-zgRX4RfyZMHuE/yYFGLfbEi2SJ1DIxp5UShOvIYZmG8=";
aarch64-linux = "sha256-ZGLzZylXnkS/0BuUz/PSGHDXRZoVqSA/+hREDp9tmsE=";
i686-linux = "sha256-qG2dpE/snBL7eVTrtX1ZP9gtCIyhPqebUo3T515uHBU=";
x86_64-darwin = "sha256-21OH98/vlUtnb3s4wA3iDV4b5jVnN2BFJ3AWMonHpPw=";
aarch64-darwin = "sha256-Usbwmqyo/RKUeGXCBPul14cccjawt1Des/hsr8mKA/Q=";
x86_64-linux = "sha256-TLpH6s9odZFh9LFnLiZjpcx0+W+6XrdDhja/xcixx7s=";
aarch64-linux = "sha256-QQejEfJrCB+68SXhQm7Ub763ZL72Cy+HB1be+4p4XrM=";
i686-linux = "sha256-1dFPAIBNyDQheIdszmoiHU6AmLZ1TtbT+If7n8ZQQAY=";
x86_64-darwin = "sha256-51A12pOMaJGYacgiIIW3sqUytApDXrSWBkNl7fWqFgk=";
aarch64-darwin = "sha256-PacsdP9n7mdK/wKJW63Ajbt5G+PFPwa+XB4OEz3YUno=";
};
in
fetchzip {

View File

@ -2,16 +2,16 @@
rustPlatform.buildRustPackage rec {
pname = "riffdiff";
version = "2.25.2";
version = "2.27.0";
src = fetchFromGitHub {
owner = "walles";
repo = "riff";
rev = version;
hash = "sha256-JZWgI4yAsk+jtTyS3QZBxdAOPYmUxb7pn1SbcUeCh6Y=";
hash = "sha256-yrIZsCxoFV9LFh96asYxpAYv1KvrLq+RlqL8gZXaeak=";
};
cargoHash = "sha256-Z33CGF02rPf24LaYh+wEmmGgPPw+oxMNCgMzCrUEKqk=";
cargoHash = "sha256-tO49qAEW15q76hLcHOtniwLqGy29MZ/dabyZHYAsiME=";
meta = with lib; {
description = "A diff filter highlighting which line parts have changed";

View File

@ -31,6 +31,8 @@ lib.makeScope newScope (self:
coap = callPackage ../development/nim-packages/coap { };
csvtools = callPackage ../development/nim-packages/csvtools { };
db_connector = callPackage ../development/nim-packages/db_connector { };
docopt = callPackage ../development/nim-packages/docopt { };