-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/dconf: support generating from attrs #234615
Conversation
085113e
to
9a2b75e
Compare
eee1aba
to
2bb9b33
Compare
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/2319 |
Thanks. Will try to review this tomorrow or on Monday (if I do not forget or get sidetracked). |
059613c
to
fe57bd4
Compare
Right but we might still implement it with something like the following: @@ -68,6 +69,11 @@ rec {
else mkArray v
else if isGVariant v then
v
+ else if builtins.isAttrs v then
+ lib.throwIf
+ (v == {})
+ "Please create an empty dictionary with something like `lib.gvariant.mkEmptyArray (lib.gvariant.type.dictionaryEntryOf lib.gvariant.type.string lib.gvariant.type.int32)`"
+ (lib.mapAttrsToList mkDictionaryEntry v)
else
throw "The GVariant type of ${v} can't be inferred.";
But I have not considered all the downsides yet so it is probably best left for future PRs as well.
The use of In INI-based settings, you often have two levels: sections and keys. dconf appears hierarchical but in practice, people tend to think in two levels as well: GSettings schemas (analogous to INI sections, as they are used as such in keyfiles) and keys. This is also evidenced in the way you write the examples: test.not.locked = mkInt32 1;
test.is.locked = "locked"; not test = {
not.locked = mkInt32 1;
is.locked = "locked";
}; (Though I admit nesting would feel natural in some use cases, e.g. with relocatable schemas. But those are comparatively rare so I am still not convinced the added possibilities for silent misconfiguration is worth it.) (Actually, dconf describes itself as a key database, which is also shown in commands See also the I am not saying I will never be convinced the other way but for now I think the paths as strings close fewer doors. It can always be extended with nesting-attributes paths support or |
remove `with lib;` profiles option now accepts packages in addition to paths. profiles option is no longer internal. cfgDir definition has been inlined. pulled GIO_EXTRA_MODULES inside mkif. removed pointless comments with section headings. defined profiles are now turned into package, allowing to simplify the db update logic.
I removed all features related to the nested format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks perfect to me now. Thanks for bearing with me.
Looks like the tests do not actually run. Also, I am thinking of getting rid of diff --git a/lib/gvariant.nix b/lib/gvariant.nix
index 3142ffc5f149..06bd3ef6a297 100644
--- a/lib/gvariant.nix
+++ b/lib/gvariant.nix
@@ -66,7 +66,11 @@ rec {
else if builtins.isString v then
mkString v
else if builtins.isList v then
- mkArray v
+ let
+ vs = map mkValue v;
+ head = lib.throwIf (v == [ ]) "Attempting to create an empty array but mkValue does not allow specifying type. Please create empty array with mkArray and pass the type explicitly." (builtins.head vs);
+ in
+ mkArray head.type vs
else if isGVariant v then
v
else
@@ -75,15 +79,15 @@ rec {
/* Returns the GVariant array from the given type of the elements and a Nix list.
Type:
- mkArray :: [Any] -> gvariant
+ mkArray :: gvariant.type -> [Any] -> gvariant
Example:
# Creating a string array
- lib.gvariant.mkArray [ "a" "b" "c" ]
+ lib.gvariant.mkArray [ "a" "b" "c" ]
*/
- mkArray = elems:
+ mkArray = elemType: elems:
let
- vs = map mkValue (lib.throwIf (elems == [ ]) "Please create empty array with mkEmptyArray." elems);
+ vs = map mkValue elems;
elemType = lib.throwIfNot (lib.all (t: (head vs).type == t) (map (v: v.type) vs))
"Elements in a list should have same type."
(head vs).type;
@@ -93,19 +97,6 @@ rec {
"@${self.type} [${concatMapStringsSep "," toString self.value}]";
};
- /* Returns the GVariant array from the given empty Nix list.
-
- Type:
- mkEmptyArray :: gvariant.type -> gvariant
-
- Example:
- # Creating an empty string array
- lib.gvariant.mkEmptyArray (lib.gvariant.type.string)
- */
- mkEmptyArray = elemType: mkPrimitive (type.arrayOf elemType) [ ] // {
- __toString = self: "@${self.type} []";
- };
-
/* Returns the GVariant variant from the given Nix value. Variants are containers
of different GVariant type.
diff --git a/lib/tests/modules/gvariant.nix b/lib/tests/modules/gvariant.nix
index a792ebf85b74..d2bbbbcc88b2 100644
--- a/lib/tests/modules/gvariant.nix
+++ b/lib/tests/modules/gvariant.nix
@@ -31,12 +31,12 @@ in {
{ uint64 = mkUint64 42; }
{ array1 = [ "one" ]; }
- { array1 = mkArray [ "two" ]; }
- { array2 = mkArray [ (mkInt32 1) ]; }
- { array2 = mkArray [ (nkUint32 2) ]; }
+ { array1 = mkArray type.string [ "two" ]; }
+ { array2 = mkArray type.int32 [ (mkInt32 1) ]; }
+ { array2 = mkArray type.uint32 [ (nkUint32 2) ]; }
{ emptyArray1 = [ ]; }
- { emptyArray2 = mkEmptyArray type.uint32; }
+ { emptyArray2 = mkArray type.uint32 []; }
{ string = "foo"; }
{ string = "foo"; } |
So when the type can be inferred the user don't need to use mkArray and mkArray is only used for empty list? |
Yes.
…On Tue, 12 Sept 2023, 04:19 linsui, ***@***.***> wrote:
So when the type can be infered the user don't need to use mkArray and
mkArray is only used for empty list?
—
Reply to this email directly, view it on GitHub
<#234615 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFMEY4MAKUS27TXX4MDRNTXZ7BDZANCNFSM6AAAAAAYR2S26Y>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
Then I thought the situation doesn't change. Currently if the user want to add elements to an empty array they need to remove the mkEmptyArray and type. With your proposal, the user needs to remove the mkArray and type. |
They do not need to, the explicit constructor would be fine to use. |
How about making mkArray only require the type when creating an empty array? |
How can I fix this? |
I think having functions that take different number of arguments depending what those arguments are can be confusing (e.g. it is not possible to express it using type annotations).
One way would be adding assertions to https://github.com/NixOS/nixpkgs/blob/fff294ce97764ee8ec20aeb24b20fff114aebbd2/lib/tests/modules.sh The other would be creating file like https://github.com/NixOS/nixpkgs/blob/fff294ce97764ee8ec20aeb24b20fff114aebbd2/lib/tests/misc.nix and then adding it to nixpkgs/lib/tests/check-eval.nix Line 3 in 55ec5ae
The latter might be cleaner and faster (no need to involve the module system for anything but merging) but might require more changes. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/configuration-of-gnome-extensions/33337/2 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/need-help-for-nixos-gnome-scaling-settings/24590/12 |
Description of changes
This implementation is partly based on #189099 and home-manager's dconf implementation and addresses some related reviews. A main difference between this and #189099 is that this implementation is completely backward-compatible and has lockdown support.
Example:
Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)