Skip to content

Instantly share code, notes, and snippets.

@grahamc

grahamc/lib.nix Secret

Last active March 21, 2019 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamc/29cead72119d86c50ea43ea3746814ec to your computer and use it in GitHub Desktop.
Save grahamc/29cead72119d86c50ea43ea3746814ec to your computer and use it in GitHub Desktop.
let
isDerivation = set: (set.type or "") == "derivation";
callableWithEmptyAttrset = fn:
let
args = builtins.functionArgs fn;
defaultValueList = builtins.attrValues args;
in if args == { }
then false # plain lambda: «x: x»
else builtins.all (x: x) defaultValueList;
ofborgTypeOf = e:
let
nixType = builtins.typeOf e;
typeDescriptionHandler = {
# Primitive types first
int = _: "int";
float = _: "float";
bool = _: "bool";
string = _: "string";
path = _: "path";
"null" = _: "null";
# Fancy types
list = _: "list";
set = set:
if isDerivation set
then "derivation"
else "set";
lambda = fn:
if callableWithEmptyAttrset fn
then "callable"
else "lambda";
mystery = x: assert builtins.trace "mystery type ${builtins.typeOf x}" false; null;
};
in (typeDescriptionHandler."${nixType}" or typeDescriptionHandler.mystery) e;
makeReferrableAttrSet = e:
let
ofborgType = ofborgTypeOf e;
typeRecurser = let
id = x: x;
in {
int = id;
float = id;
bool = id;
string = id;
path = id;
"null" = id;
derivation = id;
lambda = id;
callable = lambda: lambda {};
set = set: builtins.mapAttrs
(_: value: makeReferrableAttrSet value)
set;
list = list: (builtins.foldl'
({ counter, collector}: item: {
counter = counter + 1;
collector = collector // {
"${toString counter}" = makeReferrableAttrSet item;
};
})
{ counter = 0; collector = {};}
list).collector;
mystery = x: assert builtins.trace "mystery type ${ofborgType}" false; null;
};
in (typeRecurser."${ofborgType}" or typeRecurser.mystery) e;
flattenReferrableAttrSet = attrs: let
withPrefix = prefix: attrset:
builtins.foldl'
(collector: name:
let
value = attrset."${name}";
subPrefix = prefix ++ [name];
in collector ++ (if (ofborgTypeOf value) == "set"
then withPrefix subPrefix value
else [[ subPrefix value ]]
))
[]
(builtins.attrNames attrset);
labeledList = withPrefix [] attrs;
in builtins.foldl'
(collector: elem: let
nameElems = builtins.head elem;
value = builtins.head (builtins.tail elem);
name = builtins.concatStringsSep "." nameElems;
in collector // { "${name}" = value;})
{}
labeledList;
flattenStructure = e: let
data = (makeReferrableAttrSet e);
in if (ofborgTypeOf data) == "set"
then flattenReferrableAttrSet data
else "bare";
assertTrue = v: assert v; "ok";
assertFalse = v: assert !v; "ok";
assertEq = a: b: if a == b
then "ok"
else assert builtins.trace "a:" (
builtins.trace (builtins.deepSeq a a) (
builtins.trace "does not equal b:" (
builtins.trace (builtins.deepSeq b b) false
)
)
); null;
in {
export = {
inherit flattenStructure;
};
tests = let
drv = name: derivation {
inherit name;
builder = ./ofborg.lib.nix;
system = "bogus";
};
in {
is-derivation-int = assertFalse (isDerivation 1);
is-derivation = assertTrue (isDerivation (derivation { }));
is-derivation-attrset = assertFalse (isDerivation { });
callable-attrset = assertFalse (callableWithEmptyAttrset ({ a }: a));
callable-attrset-default = assertTrue (callableWithEmptyAttrset ({ a ? true }: a));
callable-attrset-many = assertFalse (callableWithEmptyAttrset ({ a ? true, b }: a));
callable-attrset-many-default = assertTrue (callableWithEmptyAttrset ({ a ? true, b ? true }: a));
callable-attrset-hides-plain = assertTrue (callableWithEmptyAttrset ({ a ? true }: (x: a)));
callable-plain = assertFalse (callableWithEmptyAttrset (x: x));
ofborgTypeOf-int = assertEq "int" (ofborgTypeOf 1);
ofborgTypeOf-float = assertEq "float" (ofborgTypeOf 1.1);
ofborgTypeOf-bool-true = assertEq "bool" (ofborgTypeOf true);
ofborgTypeOf-bool-false = assertEq "bool" (ofborgTypeOf false);
ofborgTypeOf-string = assertEq "string" (ofborgTypeOf "hello");
ofborgTypeOf-string-path = assertEq "string" (ofborgTypeOf (builtins.toString ./.));
ofborgTypeOf-path = assertEq "path" (ofborgTypeOf ./.);
#ofborgTypeOf-path-coerced = assertEq "path" (ofborgTypeOf (builtins.toPath "/"));
ofborgTypeOf-null = assertEq "null" (ofborgTypeOf null);
ofborgTypeOf-list = assertEq "list" (ofborgTypeOf [1 2 3]);
ofborgTypeOf-derivation = assertEq "derivation" (ofborgTypeOf (derivation { }));
ofborgTypeOf-set = assertEq "set" (ofborgTypeOf { });
ofborgTypeOf-set-with-type = assertEq "set" (ofborgTypeOf { type = "hi"; });
ofborgTypeOf-callable = assertEq "callable" (ofborgTypeOf ({ a ? true}: a));
ofborgTypeOf-lambda = assertEq "lambda" (ofborgTypeOf ({ a }: a));
ofborgTypeOf-lambda-plain = assertEq "lambda" (ofborgTypeOf (a: a));
makeReferrableAttrSet-int = assertEq
1
(makeReferrableAttrSet 1);
makeReferrableAttrSet-float = assertEq
1.1
(makeReferrableAttrSet 1.1);
makeReferrableAttrSet-bool = assertEq
true
(makeReferrableAttrSet true);
makeReferrableAttrSet-string = assertEq
"hi"
(makeReferrableAttrSet "hi");
makeReferrableAttrSet-path= assertEq
./.
(makeReferrableAttrSet ./.);
makeReferrableAttrSet-null= assertEq
null
(makeReferrableAttrSet null);
makeReferrableAttrSet-derivation = assertEq
(drv "bogus")
(makeReferrableAttrSet (drv "bogus"));
makeReferrableAttrSet-list = assertEq
{
"0" = drv "bogus-0";
"1" = drv "bogus-1";
}
(makeReferrableAttrSet [
(drv "bogus-0")
(drv "bogus-1")
]);
makeReferrableAttrSet-attrset = assertEq
{ a = "hi"; }
(makeReferrableAttrSet { a = "hi"; });
/* lambdas aren't comparable :)
makeReferrableAttrSet-lambda-plain = let
lamb = x: x;
in assertEq
lamb
(makeReferrableAttrSet lamb);
*/
makeReferrableAttrSet-lambda = let
lamb = { x ? true }: x;
in assertEq
true
(makeReferrableAttrSet lamb);
makeReferrableAttrSet-recursive = assertEq
{
"a" = {
"0" = null;
"1" = {
"a" = {
"0" = "hello";
"1" = {
"0" = "hi";
"1" = "there";
};
};
"b" = {
"2" = {
"foobar" = {
"baz" = "hello";
};
};
};
};
};
}
(makeReferrableAttrSet {
a = [
null
{
"a" = [
"hello"
[ "hi" "there" ]
];
"b" = {
"2" = {
"foobar" = {
"baz" = "hello";
};
};
};
}
];
});
flattenReferrableAttrSet-simple = assertEq
{ "a.b" = true; "a.c" = false; }
(flattenReferrableAttrSet { a = { b = true; c = false; }; });
flattenReferrableAttrSet-recursive = assertEq
{
"a.0" = null;
"a.1.a.0" = "hello";
"a.1.a.1.0" = "hi";
"a.1.a.1.1" = "there";
"a.1.b.2.foobar.baz" = "hello";
}
(flattenReferrableAttrSet
{
"a" = {
"0" = null;
"1" = {
"a" = {
"0" = "hello";
"1" = {
"0" = "hi";
"1" = "there";
};
};
"b" = {
"2" = {
"foobar" = {
"baz" = "hello";
};
};
};
};
};
}
);
flattenStructure-elaborate = assertEq
{
"a.0" = null;
"a.1.a.0" = "hello";
"a.1.a.1.0" = "hi";
"a.1.a.1.1" = "there";
"a.1.b.2.foobar.baz" = "hello";
}
(flattenStructure {
a = [
null
{
"a" = [
"hello"
[ "hi" "there" ]
];
"b" = {
"2" = { x ? true}: {
"foobar" = {
"baz" = "hello";
};
};
};
}
];
});
flattenStructure-simple = assertEq
"bare"
(flattenStructure "hi");
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment