Skip to content
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

senpai: use SCFG format #4086

Closed
wants to merge 11 commits into from
27 changes: 27 additions & 0 deletions modules/lib/generators.nix
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,31 @@
in attrs: ''
${concatStringsSep "\n" (mapAttrsToList convertAttributeToKDL attrs)}
'';

toSCFG = let
inherit (lib)
concatStringsSep filterAttrs isAttrs isBool isFloat isInt isList isString
mapAttrsToList;
inherit (builtins) typeOf toJSON;

toSCFG' = v:
if isAttrs v then ''
{
${toSCFG v}
}
'' else if isList v then
concatStringsSep " " v
else if isString v then
v
else if isInt v || isFloat v || isBool v then
toJSON v
else
abort "toSCFG: type ${typeOf v} is unsupported";

filterSCFG = filterAttrs (_: val: !isNull val && val != { });

sectionSCFG = mapAttrsToList (key: val: "${key} ${toSCFG' val}");

toSCFG = v: concatStringsSep "\n" (sectionSCFG (filterSCFG v));
jleightcap marked this conversation as resolved.
Show resolved Hide resolved
in toSCFG;
}
87 changes: 72 additions & 15 deletions modules/programs/senpai.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ with lib;

let
cfg = config.programs.senpai;
cfgFmt = pkgs.formats.yaml { };
imports = [
(mkRenamedOptionModule [ "programs" "senpai" "addr" ] [
"programs"
"senpai"
"address"
])
(mkRenamedOptionModule [ "programs" "senpai" "nick" ] [
"programs"
"senpai"
"nickname"
])
];
in {
options.programs.senpai = {
enable = mkEnableOption "senpai";
Expand All @@ -16,17 +27,22 @@ in {
};
config = mkOption {
type = types.submodule {
freeformType = cfgFmt.type;
options = {
addr = mkOption {
address = mkOption {
type = types.str;
description = ''
The address (host[:port]) of the IRC server. senpai uses TLS
connections by default unless you specify no-tls option. TLS
connections default to port 6697, plain-text use port 6667.
The address (<literal>host[:port]</literal>) of the IRC server. senpai uses TLS
connections by default unless you specify tls option to be false.
TLS connections default to port 6697, plain-text use port 6667.

<literal>ircs://</literal>, <literal>irc://</literal>, and
<literal>irc+insecure://</literal> URLs are supported, in which
case only the hostname and port parts will be used. If the scheme
is ircs/irc+insecure, tls will be overriden and set to true/false
accordingly.
'';
};
nick = mkOption {
nickname = mkOption {
type = types.str;
description = ''
Your nickname, sent with a NICK IRC message. It mustn't contain
Expand All @@ -41,17 +57,37 @@ in {
reside world-readable in the Nix store.
'';
};
# TODO: remove me for the next release
no-tls = mkOption {
type = types.bool;
default = false;
description = "Disables TLS encryption.";
type = types.nullOr types.bool;
default = null;
description = ''
Specifying 'senpai.no-tls' is deprecated, Set
<literal>senpai.extraConfig = { tls = false; }</literal>
instead.
'';
};
password-cmd = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
jleightcap marked this conversation as resolved.
Show resolved Hide resolved
description = ''
Alternatively to providing your SASL authentication password
directly in plaintext, you can specify a command to be run to
fetch the password at runtime. This is useful if you store your
passwords in a separate (probably encrypted) file using `gpg` or
a command line password manager such as <literal>pass</literal>
or <literal>gopass</literal>. If a password-cmd is provided, the
value of password will be ignored and the first line of the output
of <literal>password-cmd</literal> will be used
for login.
'';
};
};
};
example = literalExpression ''
{
addr = "libera.chat:6697";
nick = "nicholas";
address = "libera.chat:6697";
nickname = "nicholas";
password = "verysecurepassword";
}
'';
Expand All @@ -61,13 +97,34 @@ in {
<manvolnum>5</manvolnum></citerefentry>.
'';
};
extraConfig = mkOption {
type = types.attrs;
default = { };
description = ''
Options that should be appended to the senpai configuration file.
'';
};
jleightcap marked this conversation as resolved.
Show resolved Hide resolved
};

config = mkIf cfg.enable {
assertions = with cfg.config; [
{
assertion = !isNull password-cmd -> isNull password;
message = "senpai: password-command overrides password!";
}
{
# TODO: remove me for the next release
assertion = isNull no-tls;
jleightcap marked this conversation as resolved.
Show resolved Hide resolved
message = ''
Specifying 'senpai.no-tls' is deprecated,
set 'senpai.extraConfig = { tls = false; }' instead.
'';
}
];
home.packages = [ cfg.package ];
xdg.configFile."senpai/senpai.yaml".source =
cfgFmt.generate "senpai.yaml" cfg.config;
xdg.configFile."senpai/senpai.scfg".text =
lib.hm.generators.toSCFG (cfg.config // cfg.extraConfig);
};

meta.maintainers = [ hm.maintainers.malvo ];
meta.maintainers = [ maintainers.jleightcap ];
ncfavier marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions tests/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import nmt {
./modules/programs/sagemath
./modules/programs/sbt
./modules/programs/scmpuff
./modules/programs/senpai
./modules/programs/sioyek
./modules/programs/sm64ex
./modules/programs/ssh
Expand Down
4 changes: 4 additions & 0 deletions tests/modules/programs/senpai/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
senpai-example-settings = ./example-settings.nix;
senpai-empty-settings = ./empty-settings.nix;
}
2 changes: 2 additions & 0 deletions tests/modules/programs/senpai/empty-settings-expected.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
address irc.libera.chat
nickname Guest123456
20 changes: 20 additions & 0 deletions tests/modules/programs/senpai/empty-settings.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ config, ... }:

{
config = {
programs.senpai = {
enable = true;
package = config.lib.test.mkStubPackage { };
config = {
address = "irc.libera.chat";
nickname = "Guest123456";
};
};

nmt.script = ''
assertFileContent \
home-files/.config/senpai/senpai.scfg \
${./empty-settings-expected.conf}
'';
};
}
15 changes: 15 additions & 0 deletions tests/modules/programs/senpai/example-settings-expected.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
address irc.libera.chat
channel #rahxephon
colors {
prompt 2
}

highlight guest senpai lenon
nickname Guest123456
pane-widths {
nicknames 16
}

password-cmd gopass show irc/guest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be password-cmd "gopass show irc/guest"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@ncfavier ncfavier Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, but password-cmd is intentionally parsed as a list of arguments to be fed to an execve-like interface, rather than a single shell command string: https://git.sr.ht/~taiite/senpai/tree/master/item/config.go#L199-214

The option should reflect that by having type nullOr (listOf str). This will avoid giving users the illusion that they can use shell syntax and quoting.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I understand. Thank you for the well reasoned response -- an option wrapping execve as a list of strings is much more correct 🙂

realname Guest von Lenon
username senpai
29 changes: 29 additions & 0 deletions tests/modules/programs/senpai/example-settings.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{ config, ... }:

{
config = {
programs.senpai = {
enable = true;
package = config.lib.test.mkStubPackage { };
config = {
address = "irc.libera.chat";
nickname = "Guest123456";
password-cmd = [ "gopass" "show" "irc/guest" ];
};
extraConfig = {
username = "senpai";
realname = "Guest von Lenon";
channel = [ "#rahxephon" ];
highlight = [ "guest" "senpai" "lenon" ];
pane-widths = { nicknames = 16; };
colors = { prompt = 2; };
};
};

nmt.script = ''
assertFileContent \
home-files/.config/senpai/senpai.scfg \
${./example-settings-expected.conf}
'';
};
}