modularise ides workings
This commit is contained in:
parent
9248cc0945
commit
caa156daf4
@ -28,7 +28,7 @@ let
|
||||
modules =
|
||||
[
|
||||
# ides
|
||||
./ides.nix
|
||||
./lib/ides.nix
|
||||
# service config and build params
|
||||
(_: {
|
||||
inherit services serviceDefs auto;
|
||||
|
439
ides.nix
439
ides.nix
@ -1,439 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
#
|
||||
# interface
|
||||
#
|
||||
options =
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
inherit (lib) types mkOption;
|
||||
serviceConfig =
|
||||
with types;
|
||||
submodule {
|
||||
options = {
|
||||
pkg = mkOption {
|
||||
type = package;
|
||||
description = "Package to use for service.";
|
||||
example = "pkgs.caddy";
|
||||
};
|
||||
exec = mkOption {
|
||||
type = str;
|
||||
description = "Alternative executable name to use from `pkg`.";
|
||||
example = "caddy";
|
||||
default = "";
|
||||
};
|
||||
args = mkOption {
|
||||
type = str;
|
||||
description = "Arguments to supply to the service binary. Writing %CFG% in this will template to your config location.";
|
||||
example = "run -c %CFG% --adapter caddyfile";
|
||||
default = "";
|
||||
};
|
||||
socket = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of socket options for the unit (see `man systemd.socket`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
ListenStream = [ "/run/user/1000/myapp.sock" ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
path = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of path options for the unit (see `man systemd.path`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
PathModified = [ "/some/path" ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
timer = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of timer options for the unit (see `man systemd.path`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
OnActiveSec = [ 50 ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
config = mkOption {
|
||||
description = "Options for setting the service's configuration.";
|
||||
default = { };
|
||||
type = submodule {
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = "Plaintext configuration to use.";
|
||||
example = ''
|
||||
http://*:8080 {
|
||||
respond "hello"
|
||||
}
|
||||
'';
|
||||
};
|
||||
ext = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = "If your service config requires a file extension, set it here. This overrides `format`'s output path'.";
|
||||
example = "json";
|
||||
};
|
||||
file = mkOption {
|
||||
type = nullOr path;
|
||||
description = "Path to config file. This overrides all other values.";
|
||||
example = "./configs/my-config.ini";
|
||||
default = null;
|
||||
};
|
||||
content = mkOption {
|
||||
type = nullOr attrs;
|
||||
description = "Attributes that define your config values.";
|
||||
default = null;
|
||||
example = {
|
||||
this = "that";
|
||||
};
|
||||
};
|
||||
format = mkOption {
|
||||
type = nullOr (enum [
|
||||
"java"
|
||||
"json"
|
||||
"yaml"
|
||||
"toml"
|
||||
"ini"
|
||||
"xml"
|
||||
"php"
|
||||
]);
|
||||
description = "Config output format.\nOne of:\n`java json yaml toml ini xml php`.";
|
||||
example = "json";
|
||||
default = null;
|
||||
};
|
||||
formatter = mkOption {
|
||||
type = types.anything;
|
||||
description = "Serialisation/writer function to apply to `content`.\n`format` will auto-apply the correct format if the option value is valid.\nShould take `path: attrs:` and return a storepath.";
|
||||
example = "pkgs.formats.yaml {}.generate";
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
serviceDefs = mkOption {
|
||||
type = types.attrsOf serviceConfig;
|
||||
description = "Concrete service definitions, as per submodule options.\nPlease put service-related options into `options.services` instead, and use this to implement those options.";
|
||||
};
|
||||
|
||||
auto = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether to autostart ides services at devshell instantiation.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
# to prevent generating docs for this option; see https://github.com/NixOS/nixpkgs/issues/293510
|
||||
_module.args = mkOption {
|
||||
internal = true;
|
||||
};
|
||||
|
||||
# for internal use
|
||||
_buildIdes = mkOption {
|
||||
type = types.attrs;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
#
|
||||
# implementation
|
||||
#
|
||||
config =
|
||||
let
|
||||
# control flow monstrosity
|
||||
branchOnConfig =
|
||||
cfg:
|
||||
{
|
||||
text,
|
||||
file,
|
||||
content,
|
||||
contentFmt,
|
||||
}:
|
||||
if (cfg.text != "") then
|
||||
text
|
||||
else if (cfg.file != null) then
|
||||
file
|
||||
else if (cfg.content != { }) then
|
||||
if (cfg.format != null) then
|
||||
content
|
||||
else if (cfg.formatter != null) then
|
||||
contentFmt
|
||||
else
|
||||
throw "`format` or `formatter` must be set for `content` value ${cfg.content}!"
|
||||
else
|
||||
"";
|
||||
in
|
||||
{
|
||||
# validate and complete the service configurations
|
||||
_buildIdes.finalServices = builtins.mapAttrs (
|
||||
name:
|
||||
{
|
||||
pkg,
|
||||
args ? "",
|
||||
exec ? "",
|
||||
config,
|
||||
path,
|
||||
socket,
|
||||
timer,
|
||||
}:
|
||||
let
|
||||
# make our best effort to use the correct binary
|
||||
bin = if (exec == "") then pkgs.lib.getExe pkg else pkgs.lib.getExe' pkg exec;
|
||||
# set file extension
|
||||
ext =
|
||||
if (config.ext != "") || (config.format != null) then "." + (config.ext or config.format) else "";
|
||||
# config hash for unique service names
|
||||
cfgHash =
|
||||
let
|
||||
# method to hash a set
|
||||
hashContent = builtins.hashString "sha256" (builtins.toJSON config.content);
|
||||
in
|
||||
branchOnConfig config {
|
||||
text = builtins.hashString "sha256" config.text;
|
||||
file = builtins.hashFile "sha256" config.file;
|
||||
content = hashContent;
|
||||
contentFmt = hashContent;
|
||||
};
|
||||
|
||||
confFile =
|
||||
let
|
||||
writers = {
|
||||
java = pkgs.formats.javaProperties { };
|
||||
json = pkgs.formats.json { };
|
||||
yaml = pkgs.formats.yaml { };
|
||||
ini = pkgs.formats.ini { };
|
||||
toml = pkgs.formats.toml { };
|
||||
xml = pkgs.formats.xml { };
|
||||
php = pkgs.formats.php { finalVariable = null; };
|
||||
};
|
||||
# final config name
|
||||
confPath = "config-${name}-${cfgHash}${ext}";
|
||||
in
|
||||
# write out config
|
||||
branchOnConfig config {
|
||||
text = pkgs.writeText confPath config.text;
|
||||
inherit (config) file;
|
||||
content = writers.${config.format}.generate confPath config.content;
|
||||
contentFmt = config.formatter confPath config.content;
|
||||
};
|
||||
# template the config path into the launch command
|
||||
cfgArgs = builtins.replaceStrings [ "%CFG%" ] [ "${confFile}" ] args;
|
||||
# flatten unit options into cli args
|
||||
sdArgs =
|
||||
let
|
||||
inherit (pkgs.lib) foldlAttrs;
|
||||
inherit (builtins) concatStringsSep;
|
||||
convertToArgList =
|
||||
prefix: name: values:
|
||||
(map (inner: "${prefix} ${name}=${inner}") values);
|
||||
writeArgListFor =
|
||||
attrs: prefix:
|
||||
if (attrs != { }) then
|
||||
concatStringsSep " " (
|
||||
foldlAttrs (
|
||||
acc: n: v:
|
||||
acc + (convertToArgList prefix n v) + " "
|
||||
) "" attrs
|
||||
)
|
||||
else
|
||||
"";
|
||||
in
|
||||
concatStringsSep " " [
|
||||
(writeArgListFor socket "--socket-property")
|
||||
(writeArgListFor path "--path-property")
|
||||
(writeArgListFor timer "--timer-property")
|
||||
];
|
||||
in
|
||||
# transform into attrs that mkWorks expects to receive
|
||||
{
|
||||
inherit
|
||||
bin
|
||||
sdArgs
|
||||
cfgArgs
|
||||
;
|
||||
unitName = "shell-${name}-${cfgHash}";
|
||||
}
|
||||
) config.serviceDefs;
|
||||
|
||||
# generate service scripts and create the shell
|
||||
_buildIdes.shell =
|
||||
let
|
||||
# create commands to run and clean up services
|
||||
mkWorks =
|
||||
name:
|
||||
{
|
||||
unitName,
|
||||
bin,
|
||||
cfgArgs,
|
||||
sdArgs,
|
||||
}:
|
||||
{
|
||||
runner = pkgs.writeShellScriptBin "run" ''
|
||||
echo "[ides]: Starting ${name}.."
|
||||
systemd-run --user -G -u ${unitName} ${sdArgs} ${bin} ${cfgArgs}
|
||||
'';
|
||||
cleaner = pkgs.writeShellScriptBin "clean" ''
|
||||
echo "[ides]: Stopping ${name}.."
|
||||
systemctl --user stop ${unitName}
|
||||
'';
|
||||
};
|
||||
|
||||
works = pkgs.lib.mapAttrs (
|
||||
name: serviceConf: mkWorks name serviceConf
|
||||
) config._buildIdes.finalServices;
|
||||
|
||||
# create the ides cli
|
||||
inherit (pkgs) writeShellScriptBin;
|
||||
inherit (pkgs.lib) foldlAttrs;
|
||||
cli =
|
||||
let
|
||||
runAll = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc + "${works.runner}/bin/run\n"
|
||||
) "" works;
|
||||
runFns = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc
|
||||
+ ''
|
||||
function run-${name}() {
|
||||
${works.runner}/bin/run
|
||||
}
|
||||
''
|
||||
) "" works;
|
||||
cleanAll = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc + "${works.cleaner}/bin/clean\n"
|
||||
) "" works;
|
||||
cleanFns = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc
|
||||
+ ''
|
||||
function clean-${name}() {
|
||||
${works.cleaner}/bin/clean
|
||||
}
|
||||
''
|
||||
) "" works;
|
||||
names = foldlAttrs (
|
||||
acc: name: _:
|
||||
acc + "${name}\n"
|
||||
) "" works;
|
||||
in
|
||||
writeShellScriptBin "ides" (
|
||||
let
|
||||
help = ''
|
||||
[ides]: use "ides [action] [target]" to control services.
|
||||
actions:
|
||||
start synonyms: run r
|
||||
- start a service
|
||||
|
||||
stop synonyms: s clean et-tu
|
||||
- stop a service
|
||||
|
||||
restart synonyms: qq
|
||||
- stop and then restart all services
|
||||
|
||||
targets
|
||||
- print a list of available targets
|
||||
|
||||
help
|
||||
- print this helpful information
|
||||
|
||||
target names are the same as the attribute used to define a service.
|
||||
an empty target will execute the action on all available services.
|
||||
|
||||
current targets:
|
||||
'';
|
||||
in
|
||||
''
|
||||
function print-help() {
|
||||
printf '${help}'
|
||||
list-targets
|
||||
}
|
||||
|
||||
function list-targets() {
|
||||
printf '${names}\n'
|
||||
}
|
||||
|
||||
${runFns}
|
||||
|
||||
function run-all() {
|
||||
${runAll}
|
||||
}
|
||||
|
||||
${cleanFns}
|
||||
|
||||
function clean-all() {
|
||||
${cleanAll}
|
||||
}
|
||||
|
||||
function action() {
|
||||
action=$1
|
||||
if [ $# -gt 1 ]; then
|
||||
shift
|
||||
for service in "$@"; do
|
||||
$action-$service
|
||||
done
|
||||
else
|
||||
$action-all
|
||||
fi
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start|run|r)
|
||||
shift
|
||||
action run $@
|
||||
;;
|
||||
clean|stop|et-tu|s)
|
||||
shift
|
||||
action clean $@
|
||||
;;
|
||||
restart|qq)
|
||||
clean-all
|
||||
run-all
|
||||
;;
|
||||
targets)
|
||||
list-targets
|
||||
;;
|
||||
-h|h|help|*)
|
||||
print-help
|
||||
;;
|
||||
esac
|
||||
''
|
||||
);
|
||||
|
||||
# create the ides shell
|
||||
final =
|
||||
let
|
||||
inherit (config._buildIdes) shellArgs;
|
||||
in
|
||||
shellArgs
|
||||
// {
|
||||
nativeBuildInputs = (shellArgs.nativeBuildInputs or [ ]) ++ [
|
||||
cli
|
||||
];
|
||||
shellHook =
|
||||
let
|
||||
autoRun =
|
||||
if config.auto then
|
||||
''
|
||||
ides run
|
||||
''
|
||||
else
|
||||
"";
|
||||
in
|
||||
(shellArgs.shellHook or "")
|
||||
+ ''
|
||||
ides help
|
||||
''
|
||||
+ autoRun;
|
||||
};
|
||||
in
|
||||
config._buildIdes.shellFn final;
|
||||
};
|
||||
}
|
188
lib/build.nix
Normal file
188
lib/build.nix
Normal file
@ -0,0 +1,188 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config =
|
||||
let
|
||||
# control flow monstrosity
|
||||
branchOnConfig =
|
||||
cfg:
|
||||
{
|
||||
text,
|
||||
file,
|
||||
content,
|
||||
contentFmt,
|
||||
}:
|
||||
if (cfg.text != "") then
|
||||
text
|
||||
else if (cfg.file != null) then
|
||||
file
|
||||
else if (cfg.content != { }) then
|
||||
if (cfg.format != null) then
|
||||
content
|
||||
else if (cfg.formatter != null) then
|
||||
contentFmt
|
||||
else
|
||||
throw "`format` or `formatter` must be set for `content` value ${cfg.content}!"
|
||||
else
|
||||
"";
|
||||
in
|
||||
{
|
||||
# validate and complete the service configurations
|
||||
_buildIdes.finalServices = builtins.mapAttrs (
|
||||
name:
|
||||
{
|
||||
pkg,
|
||||
args ? "",
|
||||
exec ? "",
|
||||
config,
|
||||
path,
|
||||
socket,
|
||||
timer,
|
||||
}:
|
||||
let
|
||||
# make our best effort to use the correct binary
|
||||
bin = if (exec == "") then pkgs.lib.getExe pkg else pkgs.lib.getExe' pkg exec;
|
||||
# set file extension
|
||||
ext =
|
||||
if (config.ext != "") || (config.format != null) then "." + (config.ext or config.format) else "";
|
||||
# config hash for unique service names
|
||||
cfgHash =
|
||||
let
|
||||
# method to hash a set
|
||||
hashContent = builtins.hashString "sha256" (builtins.toJSON config.content);
|
||||
in
|
||||
branchOnConfig config {
|
||||
text = builtins.hashString "sha256" config.text;
|
||||
file = builtins.hashFile "sha256" config.file;
|
||||
content = hashContent;
|
||||
contentFmt = hashContent;
|
||||
};
|
||||
|
||||
confFile =
|
||||
let
|
||||
writers = {
|
||||
java = pkgs.formats.javaProperties { };
|
||||
json = pkgs.formats.json { };
|
||||
yaml = pkgs.formats.yaml { };
|
||||
ini = pkgs.formats.ini { };
|
||||
toml = pkgs.formats.toml { };
|
||||
xml = pkgs.formats.xml { };
|
||||
php = pkgs.formats.php { finalVariable = null; };
|
||||
};
|
||||
# final config name
|
||||
confPath = "config-${name}-${cfgHash}${ext}";
|
||||
in
|
||||
# write out config
|
||||
branchOnConfig config {
|
||||
text = pkgs.writeText confPath config.text;
|
||||
inherit (config) file;
|
||||
content = writers.${config.format}.generate confPath config.content;
|
||||
contentFmt = config.formatter confPath config.content;
|
||||
};
|
||||
# template the config path into the launch command
|
||||
cfgArgs = builtins.replaceStrings [ "%CFG%" ] [ "${confFile}" ] args;
|
||||
# flatten unit options into cli args
|
||||
sdArgs =
|
||||
let
|
||||
inherit (pkgs.lib) foldlAttrs;
|
||||
inherit (builtins) concatStringsSep;
|
||||
convertToArgList =
|
||||
prefix: name: values:
|
||||
(map (inner: "${prefix} ${name}=${inner}") values);
|
||||
writeArgListFor =
|
||||
attrs: prefix:
|
||||
if (attrs != { }) then
|
||||
concatStringsSep " " (
|
||||
foldlAttrs (
|
||||
acc: n: v:
|
||||
acc + (convertToArgList prefix n v) + " "
|
||||
) "" attrs
|
||||
)
|
||||
else
|
||||
"";
|
||||
in
|
||||
concatStringsSep " " [
|
||||
(writeArgListFor socket "--socket-property")
|
||||
(writeArgListFor path "--path-property")
|
||||
(writeArgListFor timer "--timer-property")
|
||||
];
|
||||
in
|
||||
# transform into attrs that mkWorks expects to receive
|
||||
{
|
||||
inherit
|
||||
bin
|
||||
sdArgs
|
||||
cfgArgs
|
||||
;
|
||||
unitName = "shell-${name}-${cfgHash}";
|
||||
}
|
||||
) config.serviceDefs;
|
||||
|
||||
# generate service scripts and create the shell
|
||||
_buildIdes.shell =
|
||||
let
|
||||
# create commands to run and clean up services
|
||||
mkWorks =
|
||||
name:
|
||||
{
|
||||
unitName,
|
||||
bin,
|
||||
cfgArgs,
|
||||
sdArgs,
|
||||
}:
|
||||
{
|
||||
runner = pkgs.writeShellScriptBin "run" ''
|
||||
echo "[ides]: starting ${name}.."
|
||||
systemd-run --user -G -u ${unitName} ${sdArgs} ${bin} ${cfgArgs}
|
||||
'';
|
||||
cleaner = pkgs.writeShellScriptBin "clean" ''
|
||||
echo "[ides]: stopping ${name}.."
|
||||
systemctl --user stop ${unitName}
|
||||
'';
|
||||
};
|
||||
|
||||
works = pkgs.lib.mapAttrs (
|
||||
name: serviceConf: mkWorks name serviceConf
|
||||
) config._buildIdes.finalServices;
|
||||
|
||||
# create the ides cli
|
||||
cli = import ./cli.nix {
|
||||
inherit (pkgs) writeShellScriptBin;
|
||||
inherit (pkgs.lib) foldlAttrs;
|
||||
inherit works;
|
||||
};
|
||||
|
||||
# create the ides shell
|
||||
final =
|
||||
let
|
||||
inherit (config._buildIdes) shellArgs;
|
||||
in
|
||||
shellArgs
|
||||
// {
|
||||
nativeBuildInputs = (shellArgs.nativeBuildInputs or [ ]) ++ [
|
||||
cli
|
||||
];
|
||||
shellHook =
|
||||
let
|
||||
autoRun =
|
||||
if config.auto then
|
||||
''
|
||||
ides run
|
||||
''
|
||||
else
|
||||
"";
|
||||
in
|
||||
(shellArgs.shellHook or "")
|
||||
+ ''
|
||||
printf '[ides]: use "ides [action] [target]" to control services. type "ides help" to find out more.\n'
|
||||
''
|
||||
+ autoRun;
|
||||
};
|
||||
in
|
||||
config._buildIdes.shellFn final;
|
||||
};
|
||||
|
||||
}
|
132
lib/cli.nix
Normal file
132
lib/cli.nix
Normal file
@ -0,0 +1,132 @@
|
||||
{
|
||||
foldlAttrs,
|
||||
writeShellScriptBin,
|
||||
works,
|
||||
}:
|
||||
let
|
||||
runAll = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc + "${works.runner}/bin/run\n"
|
||||
) "" works;
|
||||
runFns = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc
|
||||
+ ''
|
||||
function run-${name}() {
|
||||
${works.runner}/bin/run
|
||||
}
|
||||
''
|
||||
) "" works;
|
||||
cleanAll = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc + "${works.cleaner}/bin/clean\n"
|
||||
) "" works;
|
||||
cleanFns = foldlAttrs (
|
||||
acc: name: works:
|
||||
acc
|
||||
+ ''
|
||||
function clean-${name}() {
|
||||
${works.cleaner}/bin/clean
|
||||
}
|
||||
''
|
||||
) "" works;
|
||||
names = foldlAttrs (
|
||||
acc: name: _:
|
||||
acc ++ [ name ]
|
||||
) [ ] works;
|
||||
help = ''
|
||||
[ides]: use "ides [action] [target]" to control services.
|
||||
actions:
|
||||
start synonyms: run r
|
||||
- start a service
|
||||
|
||||
stop synonyms: s clean et-tu
|
||||
- stop a service
|
||||
|
||||
restart synonyms: qq
|
||||
- stop and then restart all services
|
||||
|
||||
targets synonyms: t
|
||||
- print a list of available targets
|
||||
|
||||
help
|
||||
- print this helpful information
|
||||
|
||||
target names are the same as the attribute used to define a service.
|
||||
an empty target will execute the action on all available services.
|
||||
|
||||
current targets:
|
||||
'';
|
||||
in
|
||||
writeShellScriptBin "ides" ''
|
||||
targets=(${builtins.concatStringsSep " " names})
|
||||
|
||||
function print-help() {
|
||||
printf '${help}'
|
||||
list-targets
|
||||
}
|
||||
|
||||
function list-targets() {
|
||||
echo ''${targets[@]}
|
||||
}
|
||||
|
||||
function check-target() {
|
||||
found=1
|
||||
for target in "''${targets[@]}"; do
|
||||
if [ "$1" == "$target" ]; then
|
||||
found=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
printf $found
|
||||
}
|
||||
|
||||
${runFns}
|
||||
|
||||
function run-all() {
|
||||
${runAll}
|
||||
}
|
||||
|
||||
${cleanFns}
|
||||
|
||||
function clean-all() {
|
||||
${cleanAll}
|
||||
}
|
||||
|
||||
function action() {
|
||||
action=$1
|
||||
if [[ $# -gt 1 ]]; then
|
||||
shift
|
||||
for service in "$@"; do
|
||||
if [[ $(check-target $service) -eq 0 ]]; then
|
||||
$action-$service
|
||||
else
|
||||
echo "[ides]: no such target: $service"
|
||||
fi
|
||||
done
|
||||
else
|
||||
$action-all
|
||||
fi
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start|run|r)
|
||||
shift
|
||||
action run $@
|
||||
;;
|
||||
clean|stop|et-tu|s)
|
||||
shift
|
||||
action clean $@
|
||||
;;
|
||||
restart|qq)
|
||||
clean-all
|
||||
run-all
|
||||
;;
|
||||
targets|t)
|
||||
list-targets
|
||||
;;
|
||||
-h|h|help|*)
|
||||
print-help
|
||||
;;
|
||||
esac
|
||||
''
|
9
lib/ides.nix
Normal file
9
lib/ides.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./options.nix
|
||||
./build.nix
|
||||
];
|
||||
}
|
140
lib/options.nix
Normal file
140
lib/options.nix
Normal file
@ -0,0 +1,140 @@
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options =
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
inherit (lib) types mkOption;
|
||||
serviceConfig =
|
||||
with types;
|
||||
submodule {
|
||||
options = {
|
||||
pkg = mkOption {
|
||||
type = package;
|
||||
description = "Package to use for service.";
|
||||
example = "pkgs.caddy";
|
||||
};
|
||||
exec = mkOption {
|
||||
type = str;
|
||||
description = "Alternative executable name to use from `pkg`.";
|
||||
example = "caddy";
|
||||
default = "";
|
||||
};
|
||||
args = mkOption {
|
||||
type = str;
|
||||
description = "Arguments to supply to the service binary. Writing %CFG% in this will template to your config location.";
|
||||
example = "run -c %CFG% --adapter caddyfile";
|
||||
default = "";
|
||||
};
|
||||
socket = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of socket options for the unit (see `man systemd.socket`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
ListenStream = [ "/run/user/1000/myapp.sock" ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
path = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of path options for the unit (see `man systemd.path`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
PathModified = [ "/some/path" ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
timer = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
description = "List of timer options for the unit (see `man systemd.path`) - supplied as a list due to some options allowing duplicates.";
|
||||
example = {
|
||||
OnActiveSec = [ 50 ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
config = mkOption {
|
||||
description = "Options for setting the service's configuration.";
|
||||
default = { };
|
||||
type = submodule {
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = "Plaintext configuration to use.";
|
||||
example = ''
|
||||
http://*:8080 {
|
||||
respond "hello"
|
||||
}
|
||||
'';
|
||||
};
|
||||
ext = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = "If your service config requires a file extension, set it here. This overrides `format`'s output path'.";
|
||||
example = "json";
|
||||
};
|
||||
file = mkOption {
|
||||
type = nullOr path;
|
||||
description = "Path to config file. This overrides all other values.";
|
||||
example = "./configs/my-config.ini";
|
||||
default = null;
|
||||
};
|
||||
content = mkOption {
|
||||
type = nullOr attrs;
|
||||
description = "Attributes that define your config values.";
|
||||
default = null;
|
||||
example = {
|
||||
this = "that";
|
||||
};
|
||||
};
|
||||
format = mkOption {
|
||||
type = nullOr (enum [
|
||||
"java"
|
||||
"json"
|
||||
"yaml"
|
||||
"toml"
|
||||
"ini"
|
||||
"xml"
|
||||
"php"
|
||||
]);
|
||||
description = "Config output format.\nOne of:\n`java json yaml toml ini xml php`.";
|
||||
example = "json";
|
||||
default = null;
|
||||
};
|
||||
formatter = mkOption {
|
||||
type = types.anything;
|
||||
description = "Serialisation/writer function to apply to `content`.\n`format` will auto-apply the correct format if the option value is valid.\nShould take `path: attrs:` and return a storepath.";
|
||||
example = "pkgs.formats.yaml {}.generate";
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
serviceDefs = mkOption {
|
||||
type = types.attrsOf serviceConfig;
|
||||
description = "Concrete service definitions, as per submodule options.\nPlease put service-related options into `options.services` instead, and use this to implement those options.";
|
||||
};
|
||||
|
||||
auto = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether to autostart ides services at devshell instantiation.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
# to prevent generating docs for this option; see https://github.com/NixOS/nixpkgs/issues/293510
|
||||
_module.args = mkOption {
|
||||
internal = true;
|
||||
};
|
||||
|
||||
# for internal use
|
||||
_buildIdes = mkOption {
|
||||
type = types.attrs;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user