1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00

radicle: init (#5409)

Co-authored-by: Matthias Beyer <mail@beyermatthias.de>
Co-authored-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
Lorenz Leutgeb 2025-10-26 21:34:09 +01:00 committed by GitHub
parent 1830716059
commit 2aaf924e82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 547 additions and 0 deletions

View file

@ -0,0 +1,269 @@
{
config,
options,
lib,
pkgs,
...
}:
let
inherit (lib)
attrValues
filter
filterAttrs
getExe
hasSuffix
head
id
length
listToAttrs
mkDefault
mkEnableOption
mkIf
mkOption
mkPackageOption
replaceStrings
;
inherit (lib.types)
listOf
nullOr
str
submodule
;
cfg = config.programs.radicle;
opt = options.programs.radicle;
configFile = rec {
format = pkgs.formats.json { };
name = "config.json";
path = pkgs.runCommand name { nativeBuildInputs = [ cfg.cli.package ]; } ''
mkdir keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/this/is/not/a/real/key/only/a/placeholder" \
> keys/radicle.pub
cp ${format.generate name cfg.settings} ${name}
RAD_HOME=$PWD rad config
cp ${name} $out
'';
};
publicExplorerSuffix = "$rid$path";
in
{
options = {
programs.radicle = {
enable = mkEnableOption "Radicle";
cli.package = mkPackageOption pkgs "radicle-node" { };
uri = {
rad = {
browser = {
enable = mkOption {
description = "Whether to enable `rad:`-URI handling by web browser";
default =
(hasSuffix publicExplorerSuffix cfg.settings.publicExplorer) && pkgs.stdenv.hostPlatform.isLinux;
defaultText = "`true` if a suitable public explorer is detected.";
example = false;
};
preferredNode = mkOption {
type = str;
description = "The hostname of an instance of `radicle-node`, reachable via HTTPS.";
default = "iris.radicle.xyz";
example = "radicle-node.example.com";
};
};
vscode = {
enable = mkEnableOption "`rad:`-URI handling by VSCode";
extension = mkOption {
type = str;
description = "The unique identifier of the VSCode extension that should handle `rad:`-URIs.";
default = "radicle-ide-plugins-team.radicle";
};
};
};
web-rad =
let
detected =
let
detectionList = attrValues (
filterAttrs (n: _: config.programs.${n}.enable) {
librewolf = "librewolf.desktop";
firefox = "firefox.desktop";
chromium = "chromium-browser.desktop";
}
);
in
lib.optionals (detectionList == [ ]) (head detectionList);
in
{
enable = mkEnableOption "`web+rad:`-URI handling by web browser";
browser = mkOption {
description = ''
Name of the XDG Desktop Entry for your browser.
LibreWolf, Firefox and Chromium configured via home-manager will
be detected automatically. The value of this option should likely
be the same as the output of
`xdg-mime query default x-scheme-handler/https`.
'';
type = nullOr str;
default = detected;
defaultText = "Automatically detected browser.";
example = "brave.desktop";
};
};
};
settings = mkOption {
default = { };
description = "Radicle configuration, written to `~/.radicle/config.json.";
type = submodule {
freeformType = configFile.format.type;
options = {
publicExplorer = mkOption {
type = str;
description = "HTTPS URL pattern used to generate links to view content on Radicle via the browser.";
default = "https://app.radicle.xyz/nodes/$host/$rid$path";
example = "https://radicle.example.com/nodes/seed.example.com/$rid$path";
};
node = {
alias = mkOption {
type = str;
description = "Human readable alias for your node.";
default = config.home.username;
defaultText = lib.literalExpression "config.home.username";
};
listen = mkOption {
type = listOf str;
description = "Addresses to bind to and listen for inbound connections.";
default = [ ];
example = [ "127.0.0.1:58776" ];
};
};
};
};
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion =
!pkgs.hostPlatform.isLinux
-> (
(filter id [
cfg.uri.rad.browser.enable
cfg.uri.rad.vscode.enable
]) == [ ]
);
message = "`rad:`-URI handlers are only supported on Linux.";
}
{
assertion = cfg.uri.web-rad.enable -> cfg.uri.web-rad.browser != null;
message = "Could not detect preferred browser. Please set `${builtins.toString opt.uri.web-rad.browser}`.";
}
{
assertion =
1 >= length (
filter id [
cfg.uri.rad.browser.enable
cfg.uri.rad.vscode.enable
]
);
message = "At most one `rad:`-URI handler may be enabled.";
}
{
assertion =
cfg.uri.rad.browser.enable -> hasSuffix publicExplorerSuffix cfg.settings.publicExplorer;
message = "${opt.uri.rad.browser.enable} is only compatible with a public explorer URL ending in '${publicExplorerSuffix}' but '${cfg.settings.publicExplorer}' does not end with '${publicExplorerSuffix}'.";
}
];
home = {
packages = [ cfg.cli.package ];
file.".radicle/${configFile.name}".source = configFile.path;
};
xdg = {
mimeApps.defaultApplications = {
"x-scheme-handler/rad" =
let
isEnabled = cfg.uri.rad.browser.enable || cfg.uri.rad.vscode.enable;
handlerTarget =
if cfg.uri.rad.browser.enable then
"rad-to-browser.desktop"
else if cfg.uri.rad.vscode.enable then
"rad-to-vscode.desktop"
else
throw "unreachable";
handler = mkDefault handlerTarget;
in
mkIf isEnabled handler;
"x-scheme-handler/web+rad" = mkIf cfg.uri.web-rad.enable (mkDefault cfg.uri.web-rad.browser);
};
desktopEntries =
let
mkHandler =
{
name,
shortName,
prefix,
}:
{
name = "Open Radicle URIs with ${name}";
genericName = "Code Forge";
categories = [
"Development"
"RevisionControl"
];
exec = getExe (
pkgs.writeShellApplication {
name = "rad-to-${shortName}";
meta.mainProgram = "rad-to-${shortName}";
text = ''xdg-open "${prefix}$1"'';
}
);
mimeType = [ "x-scheme-handler/rad" ];
noDisplay = true;
};
toHandler = v: {
name = "rad-to-${v.shortName}";
value = mkIf cfg.uri.rad.${v.shortName}.enable (mkHandler v);
};
in
listToAttrs (
map toHandler [
{
name = "Web Browser";
shortName = "browser";
prefix =
replaceStrings
[ "$host" publicExplorerSuffix ]
[
cfg.uri.rad.browser.preferredNode
""
]
cfg.settings.publicExplorer;
}
{
name = "VSCode";
shortName = "vscode";
prefix = "vscode://${cfg.uri.rad.vscode.extension}/";
}
]
);
};
};
meta.maintainers = with lib.maintainers; [
lorenzleutgeb
matthiasbeyer
];
}