add template and docs for contributing builder

This commit is contained in:
DavHau 2021-11-08 11:47:15 +07:00
parent 791bb7638f
commit baa442739f
5 changed files with 236 additions and 151 deletions

View File

@ -22,55 +22,34 @@ In general there are 3 different types of translators
### Add a new translator
To add a new translator, execute the flakes app `contribute` which will generate a template for you. Then open the new `default.nix` file in an edtior
Clone repo and execute:
```shell
nix run .#contribute
```
... then select `translator` and answer all questions. This will generate a template.
The nix file must declare the following attributes:
In case of a `pure` or `IFD` translator:
```nix
{
# function which receives source files and returns an attribute set
# which follows the dream lock format
translate = ...;
# function which receives source files and returns either true or false
# indicating if the current translator is capable of translating these files
compatiblePaths = ;
# optionally specify additional arguments that the user can provide to the
# translator to customize its behavior
extraArgs = ...;
}
```
See the template generated by the contribute app
In case of an `impure` translator:
```nix
{
# A derivation which outputs an executable at `/bin/run`.
# The executable will be called by dream2nix for translation
#
# The first arg `$1` will be a json file containing the input parameters
# like defined in /specifications/translator-call-example.json and the
# additional arguments required according to extraArgs
#
# The program is expected to create a file at the location specified
# by the input parameter `outFile`.
# The output file must contain the dream lock data encoded as json.
translateBin = ...;
# A function which receives source files and returns either true or false
# indicating if the current translator is capable of translating these files
compatiblePaths = ;
# optionally specify additional arguments that the user can provide to the
# translator to customize its behavior
extraArgs = ...;
}
```
See the template generated by the contribute app
Ways of debugging your translator:
- run the dream2nix flake app and use the new translator
- temporarily expose internal functions of your translator, then use nix repl `nix repl ./.` and invoke a function via `translators.translators.{subsystem}.{type}.{translator-name}.some_function`
## Contribute Builder
### Add a new builder
Clone repo and execute:
```shell
nix run .#contribute
```
... then select `builder` and answer all questions. This will generate a template.

View File

@ -1,4 +1,5 @@
import os
import pathlib
import subprocess as sp
from cleo import Application, Command
from cleo.helpers import option
@ -43,7 +44,7 @@ class ContributeCommand(Command):
if not module:
module = self.choice(
'Select module type',
['translator'],
[ 'builder', 'translator'],
0
)
module = f"{module}s"
@ -80,14 +81,17 @@ class ContributeCommand(Command):
if not name:
name = self.ask('Specify name of new module:')
for path in (
module_dir + f"{subsystem}",
module_dir + f"{subsystem}/{type}",
module_dir + f"{subsystem}/{type}/{name}"):
if not os.path.isdir(path):
os.mkdir(path)
target_file = module_dir + f"{subsystem}/{type}/{name}/default.nix"
with open(dream2nix_src + f"/templates/{module}/{type}.nix") as template:
if module == 'translators':
new_path = module_dir + f"{subsystem}/{type}/{name}"
template_file = dream2nix_src + f"/templates/{module}/{type}.nix"
else:
new_path = module_dir + f"{subsystem}/{name}"
template_file = dream2nix_src + f"/templates/{module}/default.nix"
pathlib.Path(new_path).mkdir(parents=True)
target_file = f"{new_path}/default.nix"
with open(template_file) as template:
with open(target_file, 'w') as new_file:
new_file.write(template.read())

View File

@ -15,23 +15,31 @@
}:
{
# funcs
getDependencies,
getSource,
buildPackageWithOtherBuilder,
# Funcs
# attributes
subsystemAttrs,
getCyclicDependencies,
mainPackageName,
mainPackageVersion,
# AttrSet -> Bool) -> AttrSet -> [x]
getCyclicDependencies, # name: version: -> [ {name=; version=; } ]
getDependencies, # name: version: -> [ {name=; version=; } ]
getSource, # name: version: -> store-path
buildPackageWithOtherBuilder, # { builder, name, version }: -> drv
# Attributes
subsystemAttrs, # attrset
mainPackageName, # string
mainPackageVersion, # string
# attrset of pname -> versions,
# where versions is a list of version strings
packageVersions,
# overrides
# Overrides
# Those must be applied by the builder to each individual derivation
# using `utils.applyOverridesToPackage`
packageOverrides ? {},
# custom opts:
# Custom Options: (parametrize builder behavior)
# These can be passed by the user via `builderArgs`.
# All options must provide default
standalonePackageNames ? [],
...
}@args:
@ -45,9 +53,6 @@ let
isCyclic = name: version:
(getCyclicDependencies name version) != [];
mainPackageKey =
"${mainPackageName}#${mainPackageVersion}";
nodejsVersion = subsystemAttrs.nodejsVersion;
nodejs =

View File

@ -0,0 +1,86 @@
{
lib,
pkgs,
stdenv,
# dream2nix inputs
builders,
externals,
utils,
...
}:
{
# Funcs
# AttrSet -> Bool) -> AttrSet -> [x]
getCyclicDependencies, # name: version: -> [ {name=; version=; } ]
getDependencies, # name: version: -> [ {name=; version=; } ]
getSource, # name: version: -> store-path
buildPackageWithOtherBuilder, # { builder, name, version }: -> drv
# Attributes
subsystemAttrs, # attrset
mainPackageName, # string
mainPackageVersion, # string
# attrset of pname -> versions,
# where versions is a list of version strings
packageVersions,
# Overrides
# Those must be applied by the builder to each individual derivation
# using `utils.applyOverridesToPackage`
packageOverrides ? {},
# Custom Options: (parametrize builder behavior)
# These can be passed by the user via `builderArgs`.
# All options must provide default
standalonePackageNames ? [],
...
}@args:
let
b = builtins;
# the main package
defaultPackage = packages."${mainPackageName}"."${mainPackageVersion}";
# manage pakcages in attrset to prevent duplicated evaluation
packages =
lib.mapAttrs
(name: versions:
lib.genAttrs
versions
(version: makeOnePackage name version))
packageVersions;
# Generates a derivation for a specific package name + version
makeOnePackage = name: version:
let
pkg =
stdenv.mkDerivation rec {
pname = utils.sanitizeDerivationName name;
inherit version;
src = getSource name version;
buildInputs =
map
(dep: packages."${dep.name}"."${dep.version}")
(getDependencies name version);
# Implement build phases
};
in
# apply packageOverrides to current derivation
(utils.applyOverridesToPackage packageOverrides pkg name);
in
{
inherit defaultPackage packages;
}

View File

@ -12,13 +12,24 @@
{
# the input format is specified in /specifications/translator-call-example.json
# this script receives a json file including the input paths and extraArgs
translateBin = writeScriptBin "translate" ''
#!${bash}/bin/bash
set -Eeuo pipefail
# A derivation which outputs an executable at `/bin/run`.
# The executable will be called by dream2nix for translation
# The input format is specified in /specifications/translator-call-example.json.
# The first arg `$1` will be a json file containing the input parameters
# like defined in /specifications/translator-call-example.json and the
# additional arguments required according to extraArgs
#
# The program is expected to create a file at the location specified
# by the input parameter `outFile`.
# The output file must contain the dream lock data encoded as json.
translateBin = utils.writePureShellScript
[
bash
coreutils
jq
nix
]
''
# accroding to the spec, the translator reads the input from a json file
jsonInput=$1