chore(nix): move rustSimple from users.Profpatsch.writers
I think it’s solid enough to use in a wider context. Change-Id: If53e8bbb6b90fa88d73fb42730db470e822ea182 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3055 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: lukegb <lukegb@tvl.fyi>
This commit is contained in:
parent
7e888c3c7b
commit
eb41eef612
14 changed files with 184 additions and 158 deletions
97
nix/writers/default.nix
Normal file
97
nix/writers/default.nix
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
bins = depot.nix.getBins pkgs.s6-portable-utils [ "s6-ln" "s6-ls" "s6-touch" ]
|
||||||
|
;
|
||||||
|
|
||||||
|
linkTo = name: path: depot.nix.runExecline.local name {} [
|
||||||
|
"importas" "out" "out"
|
||||||
|
bins.s6-ln "-s" path "$out"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Build a rust executable.
|
||||||
|
# Takes all arguments that `pkgs.buildRustCrate` accepts.
|
||||||
|
# Rather leaky abstraction.
|
||||||
|
rustSimple = args@{name, ...}: src:
|
||||||
|
linkTo name "${rustSimpleBin args src}/bin/${name}";
|
||||||
|
|
||||||
|
# Like `rustSimple`, but put the binary in `$out/bin/`.
|
||||||
|
rustSimpleBin = {
|
||||||
|
name,
|
||||||
|
dependencies ? [],
|
||||||
|
doCheck ? true,
|
||||||
|
...
|
||||||
|
}@args: src:
|
||||||
|
(if doCheck then testRustSimple else pkgs.lib.id)
|
||||||
|
(pkgs.buildRustCrate ({
|
||||||
|
pname = name;
|
||||||
|
version = "1.0.0";
|
||||||
|
crateName = name;
|
||||||
|
crateBin = [ name ];
|
||||||
|
dependencies = dependencies;
|
||||||
|
src = pkgs.runCommandLocal "write-main.rs" {
|
||||||
|
src = src;
|
||||||
|
passAsFile = [ "src" ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/src/bin
|
||||||
|
cp "$srcPath" $out/src/bin/${name}.rs
|
||||||
|
find $out
|
||||||
|
'';
|
||||||
|
} // args));
|
||||||
|
|
||||||
|
# Build a rust library, that can be used as dependency to `rustSimple`.
|
||||||
|
# Wrapper around `pkgs.buildRustCrate`, takes all its arguments.
|
||||||
|
rustSimpleLib = {
|
||||||
|
name,
|
||||||
|
dependencies ? [],
|
||||||
|
doCheck ? true,
|
||||||
|
...
|
||||||
|
}@args: src:
|
||||||
|
(if doCheck then testRustSimple else pkgs.lib.id)
|
||||||
|
(pkgs.buildRustCrate ({
|
||||||
|
pname = name;
|
||||||
|
version = "1.0.0";
|
||||||
|
crateName = name;
|
||||||
|
dependencies = dependencies;
|
||||||
|
src = pkgs.runCommandLocal "write-lib.rs" {
|
||||||
|
src = src;
|
||||||
|
passAsFile = [ "src" ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/src
|
||||||
|
cp "$srcPath" $out/src/lib.rs
|
||||||
|
find $out
|
||||||
|
'';
|
||||||
|
} // args));
|
||||||
|
|
||||||
|
/* Takes a `buildRustCrate` derivation as an input,
|
||||||
|
* builds it with `{ buildTests = true; }` and runs
|
||||||
|
* all tests found in its `tests` dir. If they are
|
||||||
|
* all successful, `$out` will point to the crate
|
||||||
|
* built with `{ buildTests = false; }`, otherwise
|
||||||
|
* it will fail to build.
|
||||||
|
*
|
||||||
|
* See also `nix.drvSeqL` which is used to implement
|
||||||
|
* this behavior.
|
||||||
|
*/
|
||||||
|
testRustSimple = rustDrv:
|
||||||
|
let
|
||||||
|
crate = buildTests: rustDrv.override { inherit buildTests; };
|
||||||
|
tests = depot.nix.runExecline.local "${rustDrv.name}-tests-run" {} [
|
||||||
|
"importas" "out" "out"
|
||||||
|
"if" [
|
||||||
|
"pipeline" [ bins.s6-ls "${crate true}/tests" ]
|
||||||
|
"forstdin" "-o0" "test"
|
||||||
|
"importas" "test" "test"
|
||||||
|
"${crate true}/tests/$test"
|
||||||
|
]
|
||||||
|
bins.s6-touch "$out"
|
||||||
|
];
|
||||||
|
in depot.nix.drvSeqL [ tests ] (crate false);
|
||||||
|
|
||||||
|
in {
|
||||||
|
inherit
|
||||||
|
rustSimple
|
||||||
|
rustSimpleBin
|
||||||
|
rustSimpleLib
|
||||||
|
;
|
||||||
|
}
|
68
nix/writers/tests/rust.nix
Normal file
68
nix/writers/tests/rust.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ depot, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (depot.nix.writers)
|
||||||
|
rustSimple
|
||||||
|
rustSimpleLib
|
||||||
|
rustSimpleBin
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit (pkgs)
|
||||||
|
coreutils
|
||||||
|
;
|
||||||
|
|
||||||
|
run = drv: depot.nix.runExecline.local "run-${drv.name}" {} [
|
||||||
|
"if" [ drv ]
|
||||||
|
"importas" "out" "out"
|
||||||
|
"${coreutils}/bin/touch" "$out"
|
||||||
|
];
|
||||||
|
|
||||||
|
rustTransitiveLib = rustSimpleLib {
|
||||||
|
name = "transitive";
|
||||||
|
} ''
|
||||||
|
pub fn transitive(s: &str) -> String {
|
||||||
|
let mut new = s.to_string();
|
||||||
|
new.push_str(" 1 2 3");
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transitive() {
|
||||||
|
assert_eq!(transitive("foo").as_str(), "foo 1 2 3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
rustTestLib = rustSimpleLib {
|
||||||
|
name = "test_lib";
|
||||||
|
dependencies = [ rustTransitiveLib ];
|
||||||
|
} ''
|
||||||
|
extern crate transitive;
|
||||||
|
use transitive::{transitive};
|
||||||
|
pub fn test() -> String {
|
||||||
|
transitive("test")
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
rustWithLib = run (rustSimple {
|
||||||
|
name = "rust-with-lib";
|
||||||
|
dependencies = [ rustTestLib ];
|
||||||
|
} ''
|
||||||
|
extern crate test_lib;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(test_lib::test(), String::from("test 1 2 3"));
|
||||||
|
}
|
||||||
|
'');
|
||||||
|
|
||||||
|
|
||||||
|
in depot.nix.utils.drvTargets {
|
||||||
|
inherit
|
||||||
|
rustTransitiveLib
|
||||||
|
rustWithLib
|
||||||
|
;
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
netencode = {
|
netencode = {
|
||||||
rust = depot.users.Profpatsch.writers.rustSimpleLib {
|
rust = depot.nix.writers.rustSimpleLib {
|
||||||
name = "arglib-netencode";
|
name = "arglib-netencode";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.users.Profpatsch.execline.exec-helpers
|
depot.users.Profpatsch.execline.exec-helpers
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ depot, pkgs, lib, ... }:
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
exec-helpers = depot.users.Profpatsch.writers.rustSimpleLib {
|
exec-helpers = depot.nix.writers.rustSimpleLib {
|
||||||
name = "exec-helpers";
|
name = "exec-helpers";
|
||||||
} (builtins.readFile ./exec_helpers.rs);
|
} (builtins.readFile ./exec_helpers.rs);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ depot, pkgs, lib, ... }:
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
imap-idle = depot.users.Profpatsch.writers.rustSimple {
|
imap-idle = depot.nix.writers.rustSimple {
|
||||||
name = "imap-idle";
|
name = "imap-idle";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.users.Profpatsch.arglib.netencode.rust
|
depot.users.Profpatsch.arglib.netencode.rust
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
{ depot, pkgs, lib, ... }:
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
imports = {
|
netencode-rs = depot.nix.writers.rustSimpleLib {
|
||||||
inherit (depot.users.Profpatsch)
|
|
||||||
writers;
|
|
||||||
};
|
|
||||||
|
|
||||||
netencode-rs = imports.writers.rustSimpleLib {
|
|
||||||
name = "netencode";
|
name = "netencode";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.third_party.rust-crates.nom
|
depot.third_party.rust-crates.nom
|
||||||
|
@ -18,14 +13,14 @@ let
|
||||||
|
|
||||||
gen = import ./gen.nix { inherit lib; };
|
gen = import ./gen.nix { inherit lib; };
|
||||||
|
|
||||||
pretty-rs = imports.writers.rustSimpleLib {
|
pretty-rs = depot.nix.writers.rustSimpleLib {
|
||||||
name = "netencode-pretty";
|
name = "netencode-pretty";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
netencode-rs
|
netencode-rs
|
||||||
];
|
];
|
||||||
} (builtins.readFile ./pretty.rs);
|
} (builtins.readFile ./pretty.rs);
|
||||||
|
|
||||||
pretty = depot.users.Profpatsch.writers.rustSimple {
|
pretty = depot.nix.writers.rustSimple {
|
||||||
name = "netencode-pretty";
|
name = "netencode-pretty";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
netencode-rs
|
netencode-rs
|
||||||
|
@ -48,7 +43,7 @@ let
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
netencode-mustache = imports.writers.rustSimple {
|
netencode-mustache = depot.nix.writers.rustSimple {
|
||||||
name = "netencode_mustache";
|
name = "netencode_mustache";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.users.Profpatsch.arglib.netencode.rust
|
depot.users.Profpatsch.arglib.netencode.rust
|
||||||
|
@ -58,7 +53,7 @@ let
|
||||||
} (builtins.readFile ./netencode-mustache.rs);
|
} (builtins.readFile ./netencode-mustache.rs);
|
||||||
|
|
||||||
|
|
||||||
record-get = imports.writers.rustSimple {
|
record-get = depot.nix.writers.rustSimple {
|
||||||
name = "record-get";
|
name = "record-get";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
netencode-rs
|
netencode-rs
|
||||||
|
@ -87,7 +82,7 @@ let
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
record-splice-env = imports.writers.rustSimple {
|
record-splice-env = depot.nix.writers.rustSimple {
|
||||||
name = "record-splice-env";
|
name = "record-splice-env";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
netencode-rs
|
netencode-rs
|
||||||
|
@ -116,7 +111,7 @@ let
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
env-splice-record = imports.writers.rustSimple {
|
env-splice-record = depot.nix.writers.rustSimple {
|
||||||
name = "env-splice-record";
|
name = "env-splice-record";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
netencode-rs
|
netencode-rs
|
||||||
|
|
|
@ -27,7 +27,7 @@ let
|
||||||
return res
|
return res
|
||||||
'';
|
'';
|
||||||
|
|
||||||
rust-netstring = depot.users.Profpatsch.writers.rustSimpleLib {
|
rust-netstring = depot.nix.writers.rustSimpleLib {
|
||||||
name = "netstring";
|
name = "netstring";
|
||||||
} ''
|
} ''
|
||||||
pub fn to_netstring(s: &[u8]) -> Vec<u8> {
|
pub fn to_netstring(s: &[u8]) -> Vec<u8> {
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (depot.users.Profpatsch.netstring)
|
|
||||||
python-netstring
|
|
||||||
rust-netstring
|
|
||||||
;
|
|
||||||
|
|
||||||
python-netstring-test = depot.users.Profpatsch.writers.python3 {
|
python-netstring-test = depot.users.Profpatsch.writers.python3 {
|
||||||
name = "python-netstring-test";
|
name = "python-netstring-test";
|
||||||
libraries = p: [
|
libraries = p: [
|
||||||
python-netstring
|
depot.users.Profpatsch.netstring.python-netstring
|
||||||
];
|
];
|
||||||
} ''
|
} ''
|
||||||
import netstring
|
import netstring
|
||||||
|
@ -38,10 +33,10 @@ let
|
||||||
)
|
)
|
||||||
'';
|
'';
|
||||||
|
|
||||||
rust-netstring-test = depot.users.Profpatsch.writers.rustSimple {
|
rust-netstring-test = depot.nix.writers.rustSimple {
|
||||||
name = "rust-netstring-test";
|
name = "rust-netstring-test";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
rust-netstring
|
depot.users.Profpatsch.netstring.rust-netstring
|
||||||
];
|
];
|
||||||
} ''
|
} ''
|
||||||
extern crate netstring;
|
extern crate netstring;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
read-http = depot.users.Profpatsch.writers.rustSimple {
|
read-http = depot.nix.writers.rustSimple {
|
||||||
name = "read-http";
|
name = "read-http";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.third_party.rust-crates.ascii
|
depot.third_party.rust-crates.ascii
|
||||||
|
|
|
@ -6,7 +6,7 @@ let
|
||||||
// depot.nix.getBins pkgs.bc [ "bc" ]
|
// depot.nix.getBins pkgs.bc [ "bc" ]
|
||||||
// depot.nix.getBins pkgs.ocamlPackages.sexp [ "sexp" ];
|
// depot.nix.getBins pkgs.ocamlPackages.sexp [ "sexp" ];
|
||||||
|
|
||||||
print-ast = depot.users.Profpatsch.writers.rustSimple {
|
print-ast = depot.nix.writers.rustSimple {
|
||||||
name = "print-ast";
|
name = "print-ast";
|
||||||
dependencies = with depot.third_party.rust-crates; [
|
dependencies = with depot.third_party.rust-crates; [
|
||||||
libloading
|
libloading
|
||||||
|
@ -58,7 +58,7 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
watch-file-modified = depot.users.Profpatsch.writers.rustSimple {
|
watch-file-modified = depot.nix.writers.rustSimple {
|
||||||
name = "watch-file-modified";
|
name = "watch-file-modified";
|
||||||
dependencies = [
|
dependencies = [
|
||||||
depot.third_party.rust-crates.inotify
|
depot.third_party.rust-crates.inotify
|
||||||
|
|
|
@ -67,90 +67,10 @@ let
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
rustSimple = args@{name, ...}: src:
|
|
||||||
linkTo name "${rustSimpleBin args src}/bin/${name}";
|
|
||||||
|
|
||||||
linkTo = name: path: depot.nix.runExecline.local name {} [
|
|
||||||
"importas" "out" "out"
|
|
||||||
bins.s6-ln "-s" path "$out"
|
|
||||||
];
|
|
||||||
|
|
||||||
rustSimpleBin = {
|
|
||||||
name,
|
|
||||||
dependencies ? [],
|
|
||||||
doCheck ? true,
|
|
||||||
...
|
|
||||||
}@args: src:
|
|
||||||
(if doCheck then testRustSimple else pkgs.lib.id)
|
|
||||||
(pkgs.buildRustCrate ({
|
|
||||||
pname = name;
|
|
||||||
version = "1.0.0";
|
|
||||||
crateName = name;
|
|
||||||
crateBin = [ name ];
|
|
||||||
dependencies = dependencies;
|
|
||||||
src = pkgs.runCommandLocal "write-main.rs" {
|
|
||||||
src = src;
|
|
||||||
passAsFile = [ "src" ];
|
|
||||||
} ''
|
|
||||||
mkdir -p $out/src/bin
|
|
||||||
cp "$srcPath" $out/src/bin/${name}.rs
|
|
||||||
find $out
|
|
||||||
'';
|
|
||||||
} // args));
|
|
||||||
|
|
||||||
rustSimpleLib = {
|
|
||||||
name,
|
|
||||||
dependencies ? [],
|
|
||||||
doCheck ? true,
|
|
||||||
...
|
|
||||||
}@args: src:
|
|
||||||
(if doCheck then testRustSimple else pkgs.lib.id)
|
|
||||||
(pkgs.buildRustCrate ({
|
|
||||||
pname = name;
|
|
||||||
version = "1.0.0";
|
|
||||||
crateName = name;
|
|
||||||
dependencies = dependencies;
|
|
||||||
src = pkgs.runCommandLocal "write-lib.rs" {
|
|
||||||
src = src;
|
|
||||||
passAsFile = [ "src" ];
|
|
||||||
} ''
|
|
||||||
mkdir -p $out/src
|
|
||||||
cp "$srcPath" $out/src/lib.rs
|
|
||||||
find $out
|
|
||||||
'';
|
|
||||||
} // args));
|
|
||||||
|
|
||||||
/* Takes a `buildRustCrate` derivation as an input,
|
|
||||||
* builds it with `{ buildTests = true; }` and runs
|
|
||||||
* all tests found in its `tests` dir. If they are
|
|
||||||
* all successful, `$out` will point to the crate
|
|
||||||
* built with `{ buildTests = false; }`, otherwise
|
|
||||||
* it will fail to build.
|
|
||||||
*
|
|
||||||
* See also `nix.drvSeqL` which is used to implement
|
|
||||||
* this behavior.
|
|
||||||
*/
|
|
||||||
testRustSimple = rustDrv:
|
|
||||||
let
|
|
||||||
crate = buildTests: rustDrv.override { inherit buildTests; };
|
|
||||||
tests = depot.nix.runExecline.local "${rustDrv.name}-tests-run" {} [
|
|
||||||
"importas" "out" "out"
|
|
||||||
"if" [
|
|
||||||
"pipeline" [ bins.s6-ls "${crate true}/tests" ]
|
|
||||||
"forstdin" "-o0" "test"
|
|
||||||
"importas" "test" "test"
|
|
||||||
"${crate true}/tests/$test"
|
|
||||||
]
|
|
||||||
bins.s6-touch "$out"
|
|
||||||
];
|
|
||||||
in drvSeqL [ tests ] (crate false);
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
inherit
|
inherit
|
||||||
python3
|
python3
|
||||||
python3Lib
|
python3Lib
|
||||||
rustSimple
|
|
||||||
rustSimpleBin
|
|
||||||
rustSimpleLib
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,6 @@ let
|
||||||
inherit (depot.users.Profpatsch.writers)
|
inherit (depot.users.Profpatsch.writers)
|
||||||
python3Lib
|
python3Lib
|
||||||
python3
|
python3
|
||||||
rustSimple
|
|
||||||
rustSimpleLib
|
|
||||||
rustSimpleBin
|
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (pkgs)
|
inherit (pkgs)
|
||||||
|
@ -44,54 +41,8 @@ let
|
||||||
assert(test_lib.test() == "test 1 2 3")
|
assert(test_lib.test() == "test 1 2 3")
|
||||||
'');
|
'');
|
||||||
|
|
||||||
|
|
||||||
rustTransitiveLib = rustSimpleLib {
|
|
||||||
name = "transitive";
|
|
||||||
} ''
|
|
||||||
pub fn transitive(s: &str) -> String {
|
|
||||||
let mut new = s.to_string();
|
|
||||||
new.push_str(" 1 2 3");
|
|
||||||
new
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_transitive() {
|
|
||||||
assert_eq!(transitive("foo").as_str(), "foo 1 2 3")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
rustTestLib = rustSimpleLib {
|
|
||||||
name = "test_lib";
|
|
||||||
dependencies = [ rustTransitiveLib ];
|
|
||||||
} ''
|
|
||||||
extern crate transitive;
|
|
||||||
use transitive::{transitive};
|
|
||||||
pub fn test() -> String {
|
|
||||||
transitive("test")
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
rustWithLib = run (rustSimple {
|
|
||||||
name = "rust-with-lib";
|
|
||||||
dependencies = [ rustTestLib ];
|
|
||||||
} ''
|
|
||||||
extern crate test_lib;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
assert_eq!(test_lib::test(), String::from("test 1 2 3"));
|
|
||||||
}
|
|
||||||
'');
|
|
||||||
|
|
||||||
|
|
||||||
in depot.nix.utils.drvTargets {
|
in depot.nix.utils.drvTargets {
|
||||||
inherit
|
inherit
|
||||||
pythonWithLib
|
pythonWithLib
|
||||||
rustTransitiveLib
|
|
||||||
rustWithLib
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ depot, pkgs, ... }:
|
{ depot, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (depot.users.Profpatsch.writers)
|
inherit (depot.nix.writers)
|
||||||
rustSimpleBin
|
rustSimpleBin
|
||||||
;
|
;
|
||||||
in
|
in
|
||||||
|
|
|
@ -14,7 +14,7 @@ let
|
||||||
assertDoesNotThrow
|
assertDoesNotThrow
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (depot.users.Profpatsch.writers)
|
inherit (depot.nix.writers)
|
||||||
rustSimple
|
rustSimple
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue