mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-12-25 23:41:42 +03:00
645c6fd98e
* refactor: implement a validation system for builders / translators etc, organize files * refactor: use seq instead of complicated validation function for validator * feat: allow adding discoverers, translators and builders via config * refactor: rework discoverers to use makeSubsystemModules as well * fix: validate extra modules properly * feat: support inline modules * feat: use extra attribute for extending * feat: make fetchers extensible properly * fix: add name to extra fetchers * feat: support list for extra * docs: add some comment to lib/modules.nix * fix: get extra module args from extraArgs * fix: collect all modules instead of only collecting modules for built-in subsystems * refactor: minor improvements * refactor: improve how default subsystem modules are declared * fix: translators and builders are directly under subsystem now * fix: correct attribute path, remove unused argument * fix: correct translators attribute paths * fix: correct file paths and translators attribute paths * fix: use correct translator attr path in wrapPureTranslator * fix: update unit tests code * fix: remove extra paranthesis in unit tests code * tests: add an extended dream2nix example * refactor: replace recursiveUpdate usage with normal update op * tests: fix and extend d2n-extended example * fix: pass config to d2n instance in wrap pure translator script * fix: correct toFile usage * fix: pass config to dlib in more places * fix: pass config to d2n instance in aggregated hashes cli and gomod2nix translator * refactor: remove unused extra modules validation, add warning for function modules * fix: remove non-existent inherited variable * docs: update translator attr path in contributors guide * docs: add docs for extending dream2nix * refactor: comment more code, warn for function modules only if extra is an attrset decl * docs: fix some typos * docs: explain some stuff in extending d2n better * fix: print function modules warning when it is a function * tests: add a new example that tests adding new subsystem and config.extra as nix file * tests: use cargo-toml as translator on d2n-extended to potentially catch more bugs * feat: add ifd warning for builders * tests: use build-rust-package builder instead of crane builder in d2n-extended to also test it instead of only testing crane builder * fix(rust/builders): always write the generated Cargo.lock so it doesnt get out of sync with our dream-lock * fix(rust/builders): delete cargo lock before writing it? * refactor: also print ifd warnings for translators * docs: link extending d2n doc in readme, link examples in extending d2n * docs: example naming (translators.new -> translators.example-translator) * feat: allow setting nix files for modules declarations (eg. subsystems, subsystems.translators) * refactor: move IFD warnings to src/lib/builders.nix / translators.nix respectively * refactor: throw instead of warning if function declarations for modules are used * refactor: fix throw usage * refactor: improve modules code * chore(deps): update nixpkgs * fix: correct some map usages * fix: use correct attr path for extra modules * chore: update examples flake inputs * style: minor formatting changes
308 lines
8.2 KiB
Python
308 lines
8.2 KiB
Python
import nix_ffi
|
|
import os
|
|
import pytest
|
|
|
|
|
|
def get_projects_to_test():
|
|
tests = nix_ffi.eval(
|
|
'subsystems.allTranslators',
|
|
wrapper_code = '''
|
|
{result}: let
|
|
lib = (import <nixpkgs> {}).lib;
|
|
l = lib // builtins;
|
|
in
|
|
l.flatten (
|
|
l.map
|
|
(
|
|
translator:
|
|
l.map
|
|
(source: {
|
|
source = l.toString source;
|
|
translator = translator.name;
|
|
inherit (translator) subsystem type;
|
|
})
|
|
(translator.generateUnitTestsForProjects or [])
|
|
)
|
|
result
|
|
)
|
|
''',
|
|
)
|
|
result = []
|
|
for test in tests:
|
|
if test['type'] == 'all':
|
|
continue
|
|
result.append(dict(
|
|
project = dict(
|
|
name="test",
|
|
relPath="",
|
|
translator=test['translator'],
|
|
subsystemInfo={},
|
|
),
|
|
translator=test['translator'],
|
|
source = test['source'],
|
|
subsystem = test['subsystem'],
|
|
type = test['type'],
|
|
))
|
|
return result
|
|
|
|
|
|
projects = get_projects_to_test()
|
|
|
|
|
|
def check_format_dependencies(dependencies):
|
|
assert isinstance(dependencies, list)
|
|
for dep in dependencies:
|
|
assert set(dep.keys()) == {'name', 'version'}
|
|
assert isinstance(dep['name'], str)
|
|
assert len(dep['name']) > 0
|
|
assert isinstance(dep['version'], str)
|
|
assert len(dep['version']) > 0
|
|
|
|
def check_format_sourceSpec(sourceSpec):
|
|
assert isinstance(sourceSpec, dict)
|
|
assert 'type' in sourceSpec
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_packageName(p):
|
|
defaultPackage = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.defaultPackage
|
|
''',
|
|
)
|
|
assert isinstance(defaultPackage, str)
|
|
assert len(defaultPackage) > 0
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_exportedPackages(p):
|
|
exportedPackages = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.exportedPackages
|
|
''',
|
|
)
|
|
assert isinstance(exportedPackages, dict)
|
|
assert len(exportedPackages) > 0
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_extraDependencies(p):
|
|
extraDependencies = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.extraDependencies
|
|
''',
|
|
)
|
|
assert isinstance(extraDependencies, list)
|
|
for extra_dep in extraDependencies:
|
|
assert set(extra_dep.keys()) == {"dependencies", "name", "version"}
|
|
assert isinstance(extra_dep['name'], str)
|
|
assert len(extra_dep['name']) > 0
|
|
assert isinstance(extra_dep['version'], str)
|
|
assert len(extra_dep['version']) > 0
|
|
check_format_dependencies(extra_dep['dependencies'])
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_extraObjects(p):
|
|
extraObjects = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.extraObjects
|
|
''',
|
|
)
|
|
assert isinstance(extraObjects, list)
|
|
for extra_obj in extraObjects:
|
|
assert set(extra_obj.keys()) == \
|
|
{'name', 'version', 'dependencies', 'sourceSpec'}
|
|
assert isinstance(extra_obj['name'], str)
|
|
assert len(extra_obj['name']) > 0
|
|
assert isinstance(extra_obj['version'], str)
|
|
assert len(extra_obj['version']) > 0
|
|
check_format_dependencies(extra_obj['dependencies'])
|
|
check_format_sourceSpec(extra_obj['sourceSpec'])
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_location(p):
|
|
location = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.location
|
|
''',
|
|
)
|
|
assert isinstance(location, str)
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_serializedRawObjects(p):
|
|
serializedRawObjects = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
|
|
result.inputs.serializedRawObjects
|
|
''',
|
|
)
|
|
assert isinstance(serializedRawObjects, list)
|
|
for raw_obj in serializedRawObjects:
|
|
assert isinstance(raw_obj, dict)
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_subsystemName(p):
|
|
subsystemName = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.subsystemName
|
|
''',
|
|
)
|
|
assert isinstance(subsystemName, str)
|
|
assert len(subsystemName) > 0
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_subsystemAttrs(p):
|
|
subsystemAttrs = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.subsystemAttrs
|
|
''',
|
|
)
|
|
assert isinstance(subsystemAttrs, dict)
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_translatorName(p):
|
|
translatorName = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
result.inputs.translatorName
|
|
''',
|
|
)
|
|
assert isinstance(translatorName, str)
|
|
assert len(translatorName) > 0
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_extractors(p):
|
|
finalObjects = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
let
|
|
l = builtins;
|
|
inputs = result.inputs;
|
|
rawObjects = inputs.serializedRawObjects;
|
|
|
|
finalObjects =
|
|
l.map
|
|
(rawObj: let
|
|
finalObj =
|
|
l.mapAttrs
|
|
(key: extractFunc: extractFunc rawObj finalObj)
|
|
inputs.extractors;
|
|
in
|
|
finalObj)
|
|
rawObjects;
|
|
in
|
|
finalObjects ++ (inputs.extraObjects or [])
|
|
''',
|
|
)
|
|
assert isinstance(finalObjects, list)
|
|
assert len(finalObjects) > 0
|
|
for finalObj in finalObjects:
|
|
assert set(finalObj.keys()) == \
|
|
{'name', 'version', 'sourceSpec', 'dependencies'}
|
|
check_format_dependencies(finalObj['dependencies'])
|
|
check_format_sourceSpec(finalObj['sourceSpec'])
|
|
|
|
@pytest.mark.parametrize("p", projects)
|
|
def test_keys(p):
|
|
objectsByKey = nix_ffi.eval(
|
|
f"subsystems.{p['subsystem']}.translators.{p['translator']}.translate",
|
|
params=dict(
|
|
project=p['project'],
|
|
source=p['source'],
|
|
),
|
|
wrapper_code = '''
|
|
{result}:
|
|
let
|
|
l = builtins;
|
|
inputs = result.inputs;
|
|
rawObjects = inputs.serializedRawObjects;
|
|
|
|
finalObjects =
|
|
l.map
|
|
(rawObj: let
|
|
finalObj =
|
|
{inherit rawObj;}
|
|
// l.mapAttrs
|
|
(key: extractFunc: extractFunc rawObj finalObj)
|
|
inputs.extractors;
|
|
in
|
|
finalObj)
|
|
rawObjects;
|
|
|
|
objectsByKey =
|
|
l.mapAttrs
|
|
(key: keyFunc:
|
|
l.foldl'
|
|
(merged: finalObj:
|
|
merged
|
|
// {"${keyFunc finalObj.rawObj finalObj}" = finalObj;})
|
|
{}
|
|
(finalObjects ++ (inputs.extraObjects or [])))
|
|
inputs.keys;
|
|
in
|
|
objectsByKey
|
|
''',
|
|
)
|
|
assert isinstance(objectsByKey, dict)
|
|
for key_name, objects in objectsByKey.items():
|
|
for finalObj in objects.values():
|
|
assert set(finalObj.keys()) == \
|
|
{'name', 'version', 'sourceSpec', 'dependencies', 'rawObj'}
|
|
check_format_dependencies(finalObj['dependencies'])
|
|
check_format_sourceSpec(finalObj['sourceSpec'])
|