nix-community / dconf2nix

:feet: Convert dconf files (e.g. GNOME Shell) to Nix, as expected by Home Manager [maintainer=@jtojnar]

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JSON-like values still need a tiny fix

lbssousa opened this issue · comments

This is a follow up of issue #37

I've tested a little deeper the solution proposed in PR #38 and noticed that home-manager switch returns the following error message:

error: Key file contains line “'” which is not a key-value pair, group, or comment

In order to avoid this error, I need to remove the line breaks within the quotes, like this:

"org/gnome/shell/extensions/sound-output-device-chooser" = {
  ports-settings = ''{"version":2,"ports":[]}'';
};

How about this? This is how dconf2nix generates the entry.

"org/gnome/shell/extensions/sound-output-device-chooser" = {
  ports-settings = ''
    {"version":2,"ports":[]}
  '';
};
"org/gnome/shell/extensions/sound-output-device-chooser" = {
  ports-settings = ''
    {"version":2,"ports":[]}
  '';
};

With this form, home-manager switch ends up with that error message:

Starting home manager activation
Activating checkFilesChanged
Activating checkLinkTargets
Activating writeBoundary
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
Activating dconfSettings
error: Key file contains line “'” which is not a key-value pair, group, or comment

Okay. You're going to have to ask that to the Home Manager folks, maybe JSON is not even supported. If it requires escaping quotes or some different implementation, I'd be happy to work on it, but we need to be sure that HM supports it.

Double quoting the JSON string and escaping the quotes inside works in my testing, though I don't know if we want to wait for some official clarification on what style is preferred.

@johanbrandhorst can you share input and expected output? If that works for you, I can work on it. I don't use any JSON-like entries so this is not a problem for me :)

Sure thing. The following input:

panel-element-positions='{"0":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":true,"position":"stackedTL"},{"element":"taskbar","visible":true,"position":"stackedTL"},{"element":"centerBox","visible":true,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"dateMenu","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":true,"position":"stackedBR"}],"1":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":true,"position":"stackedTL"},{"element":"taskbar","visible":true,"position":"stackedTL"},{"element":"centerBox","visible":true,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"dateMenu","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":true,"position":"stackedBR"}]}'

Should ideally produce the following output:

panel-element-positions = "{\"0\":[{\"element\":\"showAppsButton\",\"visible\":false,\"position\":\"stackedTL\"},{\"element\":\"activitiesButton\",\"visible\":false,\"position\":\"stackedTL\"},{\"element\":\"leftBox\",\"visible\":true,\"position\":\"stackedTL\"},{\"element\":\"taskbar\",\"visible\":true,\"position\":\"stackedTL\"},{\"element\":\"centerBox\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"rightBox\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"dateMenu\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"systemMenu\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"desktopButton\",\"visible\":true,\"position\":\"stackedBR\"}],\"1\":[{\"element\":\"showAppsButton\",\"visible\":false,\"position\":\"stackedTL\"},{\"element\":\"activitiesButton\",\"visible\":false,\"position\":\"stackedTL\"},{\"element\":\"leftBox\",\"visible\":true,\"position\":\"stackedTL\"},{\"element\":\"taskbar\",\"visible\":true,\"position\":\"stackedTL\"},{\"element\":\"centerBox\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"rightBox\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"dateMenu\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"systemMenu\",\"visible\":true,\"position\":\"stackedBR\"},{\"element\":\"desktopButton\",\"visible\":true,\"position\":\"stackedBR\"}]}"; 

Ah okay so you meant escaping the double-quotes within the main double-quotes. I think this could be a potential workaround but let's wait a bit for the HM folks, I believe the current output produced by dconf2nix should be the way to go (raw JSON wrapped in double single-quotes, which allow multiline strings) since it's perfectly valid Nix.

The current output of that input is not double single quotes in my experience. It produces:

panel-element-positions = "'{"0":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":true,"position":"stackedTL"},{"element":"taskbar","visible":true,"position":"stackedTL"},{"element":"centerBox","visible":true,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"dateMenu","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":true,"position":"stackedBR"}],"1":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":true,"position":"stackedTL"},{"element":"taskbar","visible":true,"position":"stackedTL"},{"element":"centerBox","visible":true,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"dateMenu","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":true,"position":"stackedBR"}]}'";

master does indeed work fine for me, but I found a separate issue, will raise it separately.

I've received the following feedback from nix-community/home-manager#2096 (comment):

The issue seems to be that multiline strings written in that fashion have a leading newline.

I don't use the dconf module/configuration so I don't know whether HM could always strip the first newline of a string.

It could break some wild configuration out there I suppose.

According to him, the following Nix code:

# Generated via dconf2nix: https://github.com/gvolpe/dconf2nix
{ lib, ... }:

let
  mkTuple = lib.hm.gvariant.mkTuple;
in
{
  dconf.settings = {
    "org/gnome/shell/extensions/sound-output-device-chooser" = {
      ports-settings = ''
        {"version":2,"ports":[]}
      '';
    };
  };
}

may lead to the following dconf setting:

[org/gnome/shell/extensions/sound-output-device-chooser]
ports-settings='{"version":2,"ports":[]}
'

The question is: whose is the responsability from removing this trailing newline: HM itself (may it break other HM settings?), HM dconf module (can it be done for this module only?) or dconf2nix (it should generate ports-settings = ''{"version":2,"ports":[]}'';)?

HM master should now properly escape literal newlines in strings, which should fix the issue of invalid INI file generation.

That's great to hear! I'll try it out soon as I can, and close this issue if all the tests pass.

commented

This issue seems to be fixed, with dconf2nix built from master (and dash-to-panel)

Thanks for confirming @maydayv7 , I actually forgot to check. I'll close the issue then.