Compare commits

..

3 commits

Author SHA1 Message Date
Bruno BELANYI db89917840 flake: checks: enable 'typos'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-09-27 14:10:24 +00:00
Bruno BELANYI e08f3e5b2e treewide: add 'typos' ignore directives 2024-09-27 14:10:02 +00:00
Bruno BELANYI d6e77b62b4 project: add typos configuration 2024-09-27 14:09:07 +00:00
53 changed files with 397 additions and 395 deletions

7
.typos.toml Normal file
View file

@ -0,0 +1,7 @@
[default]
extend-ignore-re = [
# spellchecker:disable-line
"(?Rm)^.*(#|//|--)\\s*spellchecker:disable-line$",
# spellchecker:<on|off>
"(?s)(#|//|--)\\s*spellchecker:off.*?\\n\\s*(#|//|--)\\s*spellchecker:on",
]

View file

@ -73,11 +73,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1733312601, "lastModified": 1726153070,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -94,11 +94,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1726560853,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -136,11 +136,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1735381016, "lastModified": 1727246346,
"narHash": "sha256-CyCZFhMUkuYbSD6bxB/r43EdmDE7hYeZZPTCv0GudO4=", "narHash": "sha256-TcUaKtya339Asu+g6KTJ8h7KiKcKXKp2V+At+7tksyY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "10e99c43cdf4a0713b4e81d90691d22c6a58bdf2", "rev": "1e22ef1518fb175d762006f9cae7f6312b8caedb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -152,11 +152,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1735291276, "lastModified": 1726937504,
"narHash": "sha256-NYVcA06+blsLG6wpAbSPTCyLvxD/92Hy4vlY9WxFI1M=", "narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "634fd46801442d760e09493a794c4f15db2d0cbb", "rev": "9357f4f23713673f310988025d9dc261c20e70c6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -167,21 +167,12 @@
} }
}, },
"nur": { "nur": {
"inputs": {
"flake-parts": [
"flake-parts"
],
"nixpkgs": [
"nixpkgs"
],
"treefmt-nix": "treefmt-nix"
},
"locked": { "locked": {
"lastModified": 1735408823, "lastModified": 1727272134,
"narHash": "sha256-1VjQeMQer5nXNYtw+BG+s78ucaEoxO5oqj+yRmM8MMs=", "narHash": "sha256-q8xoi2eO23zhOmgBtJTj0QlcABoMeVB0CAWufTR3wyw=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "8283ea92deac8cdb6fd63ff04049ac9e879bf5eb", "rev": "8dbbe7f3575d0ff0998f92f811fb8bf4e3f0d3b1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -203,11 +194,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1734797603, "lastModified": 1726745158,
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=", "narHash": "sha256-D5AegvGoEjt4rkKedmxlSEmC+nNLMBPWFxvmYnVLhjk=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498", "rev": "4e743a6920eab45e8ba0fbe49dc459f1423a4b74",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -244,27 +235,6 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nur",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733222881,
"narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "49717b5af6f80172275d47a418c9719a31a78b53",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View file

@ -55,10 +55,6 @@
owner = "nix-community"; owner = "nix-community";
repo = "NUR"; repo = "NUR";
ref = "master"; ref = "master";
inputs = {
flake-parts.follows = "flake-parts";
nixpkgs.follows = "nixpkgs";
};
}; };
pre-commit-hooks = { pre-commit-hooks = {

View file

@ -26,6 +26,10 @@
stylua = { stylua = {
enable = true; enable = true;
}; };
typos = {
enable = true;
};
}; };
}; };
}; };

View file

@ -25,7 +25,7 @@ let
inherit system; inherit system;
overlays = (lib.attrValues self.overlays) ++ [ overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default inputs.nur.overlay
]; ];
}; };

View file

@ -7,7 +7,7 @@ let
} }
{ {
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [ nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default inputs.nur.overlay
]; ];
} }
# Include generic settings # Include generic settings

View file

@ -1,9 +1,8 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 cKojmg Ec0xt1uJTva8MxUdoTVX5m3uWaIiRlodf345FEM7Uzs -> ssh-ed25519 cKojmg bQFr9oAnbo1rI/MpUV8wQz/Xj7iZY4ZU+Swf0nSIQFw
aJIneWFJPB5HVeoUGp57agXih9YeZ6xMEbyQ+zJtWQY zama2XJ0gdvUlD2GHMhmZqHSxHe+dKSfXnHoWDcSw7Y
-> ssh-ed25519 jPowng B5XotRgv7s/FUegGhceBj7EoukewNUOIFl4TFRQf1EQ -> ssh-ed25519 jPowng gitUwSKTNKWLSxnwa185O7x/u0ul93g8wPESdZaKRk8
PgGCBd/Pqwp7ayqi7okHBGF1SfFpwT4KlHJ/np6p2uQ uvBIfAUkZp5sg6rfeEGvL5ZDV8m2uSEotW02kjPN3Hw
--- AeLgwGz6k3OABb53cXNaCU/sgI4FlU1s6p8PhAaFOlg --- SZxe5f/CUZBvPQa2Sz/UBY3L68rMkIGGRuZPk7YE+Vg
1ÌÉCÔ¹ð¤ŽULfI1¸Hm»Ûòb}m” ÁÅ¡ìg•ß0¦¢–¤`X<16>G>\>¹8rŽz+ŠY ™¼`—Ê¢.JBUÏ!z¸Z50ú*õ¡ÙŸ¤×ÖÇ®I<C2AE>ôÔ]¹Ïå I ¾r ú&…¥‹{~v?¨}=Ä
ĵ<18>¿oÒÛ°…g„®„ÒêÁ³Â¿Ÿt©nƒºãcz[»{ }+ ¿SQM[²]Œ±k MÒAàtŒÃmMë/£µLsü|Þ…m©CÀñiYC}ƒŽ‡çxŽ€
jçå&ÁõõNæ°Nÿo{õš½‚ -eP¾=L‰™ 6¦.SP:»e¶

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg xRtF3XVc7yPicAV/E4U7mn0itvD0h1BWBTjwunuoe2E
OkB9sjGB3ulH4Feuyj3Ed0DBG4+mghW/Qpum9oXL/8c
-> ssh-ed25519 jPowng 1r8drqhz1yZdTq0Kvqya+ArU1C2fkN7Gg9LiWWfeUFg
cjbxntVwHvqLaJpiKs/Y8ojeb6e3/cLFcsoeuoobfFg
--- B1qA2PylJBrdZxZtCzlU2kRPvxLM+IrXTvR+ERxVtTY
"W9<57>Äbg¸©~Ì/áÕb4ãÕ†ú³ÜÔIÊ
Û}ð §ËÅË-³²ªNó±”ÑC7vWœbºØ?¦8=œÉwÆB ÃUpJClï²OÈ™³œnOÁ\

View file

@ -48,6 +48,9 @@ in
owner = "matrix-synapse"; owner = "matrix-synapse";
publicKeys = all; publicKeys = all;
}; };
"matrix/sliding-sync-secret.age" = {
publicKeys = all;
};
"mealie/mail.age" = { "mealie/mail.age" = {
publicKeys = all; publicKeys = all;

View file

@ -69,6 +69,9 @@ in
mailConfigFile = secrets."matrix/mail".path; mailConfigFile = secrets."matrix/mail".path;
# Only necessary when doing the initial registration # Only necessary when doing the initial registration
secretFile = secrets."matrix/secret".path; secretFile = secrets."matrix/secret".path;
slidingSync = {
secretFile = secrets."matrix/sliding-sync-secret".path;
};
}; };
mealie = { mealie = {
enable = true; enable = true;
@ -95,9 +98,6 @@ in
nextcloud = { nextcloud = {
enable = true; enable = true;
passwordFile = secrets."nextcloud/password".path; passwordFile = secrets."nextcloud/password".path;
collabora = {
enable = true;
};
}; };
nix-cache = { nix-cache = {
enable = true; enable = true;
@ -132,6 +132,13 @@ in
enable = true; enable = true;
loginFile = secrets."pdf-edit/login".path; loginFile = secrets."pdf-edit/login".path;
}; };
# Podcast automatic downloader
podgrab = {
enable = true;
passwordFile = secrets."podgrab/password".path;
dataDir = "/data/media/podcasts";
port = 9598;
};
# Regular backups # Regular backups
postgresql-backup.enable = true; postgresql-backup.enable = true;
pyload = { pyload = {
@ -152,6 +159,11 @@ in
}; };
# Because I still need to play sysadmin # Because I still need to play sysadmin
ssh-server.enable = true; ssh-server.enable = true;
# Recipe manager
tandoor-recipes = {
enable = true;
secretKeyFile = secrets."tandoor-recipes/secret-key".path;
};
# Torrent client and webui # Torrent client and webui
transmission = { transmission = {
enable = true; enable = true;

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
# shellcheck disable=2155 # shellcheck disable=2155
use_android() { use_android() {
@ -32,16 +32,10 @@ use_android() {
-b|--build-tools) -b|--build-tools)
build_tools_version="$2" build_tools_version="$2"
shift 2 shift 2
if ! [ -e "$ANDROID_HOME/build-tools/$build_tools_version" ]; then
log_error "use_android: build-tools version '$build_tools_version' does not exist"
fi
;; ;;
-n|--ndk) -n|--ndk)
ndk_version="$2" ndk_version="$2"
shift 2 shift 2
if ! [ -e "$ANDROID_HOME/ndk/$ndk_version" ]; then
log_error "use_android: NDK version '$ndk_version' does not exist"
fi
;; ;;
--) --)
shift shift

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
use_pkgs() { use_pkgs() {
if ! has nix; then if ! has nix; then

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
layout_postgres() { layout_postgres() {
if ! has postgres || ! has initdb; then if ! has postgres || ! has initdb; then

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
layout_poetry() { layout_poetry() {
if ! has poetry; then if ! has poetry; then
@ -53,5 +53,4 @@ layout_uv() {
PATH_add "$VIRTUAL_ENV/bin" PATH_add "$VIRTUAL_ENV/bin"
watch_file pyproject.toml watch_file pyproject.toml
watch_file uv.lock watch_file uv.lock
watch_file .python-version
} }

View file

@ -22,10 +22,6 @@ in
options.my.home.nix = with lib; { options.my.home.nix = with lib; {
enable = my.mkDisableOption "nix configuration"; enable = my.mkDisableOption "nix configuration";
gc = {
enable = my.mkDisableOption "nix GC configuration";
};
cache = { cache = {
selfHosted = my.mkDisableOption "self-hosted cache"; selfHosted = my.mkDisableOption "self-hosted cache";
}; };
@ -64,22 +60,6 @@ in
}; };
} }
(lib.mkIf cfg.gc.enable {
nix.gc = {
automatic = true;
# Every week, with some wiggle room
frequency = "weekly";
randomizedDelaySec = "10min";
# Use a persistent timer for e.g: laptops
persistent = true;
# Delete old profiles automatically after 15 days
options = "--delete-older-than 15d";
};
})
(lib.mkIf cfg.cache.selfHosted { (lib.mkIf cfg.cache.selfHosted {
nix = { nix = {
settings = { settings = {

View file

@ -26,7 +26,6 @@ in
fd fd
file file
ripgrep ripgrep
tree
] ++ cfg.additionalPackages); ] ++ cfg.additionalPackages);
nixpkgs.config = { nixpkgs.config = {

View file

@ -47,8 +47,6 @@ in
clock24 = true; # I'm one of those heathens clock24 = true; # I'm one of those heathens
escapeTime = 0; # Let vim do its thing instead escapeTime = 0; # Let vim do its thing instead
historyLimit = 100000; # Bigger buffer historyLimit = 100000; # Bigger buffer
mouse = false; # I dislike mouse support
focusEvents = true; # Report focus events
terminal = "tmux-256color"; # I want accurate termcap info terminal = "tmux-256color"; # I want accurate termcap info
plugins = with pkgs.tmuxPlugins; [ plugins = with pkgs.tmuxPlugins; [
@ -82,13 +80,6 @@ in
]; ];
extraConfig = '' extraConfig = ''
# Refresh configuration
bind-key -N "Source tmux.conf" R source-file ${config.xdg.configHome}/tmux/tmux.conf \; display-message "Sourced tmux.conf!"
# Accept sloppy Ctrl key when switching windows, on top of default mapping
bind-key -N "Select the previous window" C-p previous-window
bind-key -N "Select the next window" C-n next-window
# Better vim mode # Better vim mode
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'v' send -X begin-selection
${ ${

View file

@ -1,6 +0,0 @@
" Create the `b:undo_ftplugin` variable if it doesn't exist
call ftplugined#check_undo_ft()
" Use a small indentation value on query files
setlocal shiftwidth=2
let b:undo_ftplugin.='|setlocal shiftwidth<'

View file

@ -109,13 +109,13 @@ local keys = {
{ "yoc", desc = "Cursor line" }, { "yoc", desc = "Cursor line" },
{ "yod", desc = "Diff" }, { "yod", desc = "Diff" },
{ "yof", "<cmd>FormatToggle<CR>", desc = "LSP Formatting" }, { "yof", "<cmd>FormatToggle<CR>", desc = "LSP Formatting" },
{ "yoh", desc = "Search high-lighting" }, { "yoh", desc = "Search high-lighting" }, -- spellchecker:disable-line
{ "yoi", desc = "Case insensitive search" }, { "yoi", desc = "Case insensitive search" },
{ "yol", desc = "List mode" }, { "yol", desc = "List mode" },
{ "yon", desc = "Line numbers" }, { "yon", desc = "Line numbers" },
{ "yop", "<Plug>(qf_loc_toggle)", desc = "Location list" }, { "yop", "<Plug>(qf_loc_toggle)", desc = "Location list" },
{ "yoq", "<Plug>(qf_qf_toggle)", desc = "Quickfix list" }, { "yoq", "<Plug>(qf_qf_toggle)", desc = "Quickfix list" },
{ "yor", desc = "Relative line numbers" }, { "yor", desc = "Relative line numbers" }, -- spellchecker:disable-line
{ "you", desc = "Cursor column" }, { "you", desc = "Cursor column" },
{ "yov", desc = "Virtual editing" }, { "yov", desc = "Virtual editing" },
{ "yow", desc = "Text wrapping" }, { "yow", desc = "Text wrapping" },

View file

@ -100,9 +100,6 @@ in
# Shell # Shell
bash-language-server bash-language-server
shfmt shfmt
# Generic
typos-lsp
]; ];
}; };

View file

@ -102,11 +102,7 @@ gruvbox.setup({
DiffText = { fg = colors.yellow, bg = colors.bg0 }, DiffText = { fg = colors.yellow, bg = colors.bg0 },
-- Directories "pop" better in blue -- Directories "pop" better in blue
Directory = { link = "GruvboxBlueBold" }, Directory = { link = "GruvboxBlueBold" },
}, }
italic = {
-- Comments should not be italic, for e.g: box drawing
comments = false,
},
}) })
EOF EOF
" Use my preferred colorscheme " Use my preferred colorscheme

View file

@ -74,16 +74,6 @@ if utils.is_executable("bash-language-server") then
filetypes = { "bash", "sh", "zsh" }, filetypes = { "bash", "sh", "zsh" },
capabilities = capabilities, capabilities = capabilities,
on_attach = lsp.on_attach, on_attach = lsp.on_attach,
settings = {
bashIde = {
shfmt = {
-- Simplify the code
simplifyCode = true,
-- Indent switch cases
caseIndent = true,
},
},
},
}) })
end end
@ -94,11 +84,3 @@ if utils.is_executable("starpls") then
on_attach = lsp.on_attach, on_attach = lsp.on_attach,
}) })
end end
-- Generic
if utils.is_executable("typos-lsp") then
lspconfig.typos_lsp.setup({
capabilities = capabilities,
on_attach = lsp.on_attach,
})
end

View file

@ -46,3 +46,29 @@ null_ls.register({
condition = utils.is_executable_condition("isort"), condition = utils.is_executable_condition("isort"),
}), }),
}) })
-- Shell (non-POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use bash dialect
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "bash" },
-- Restrict to bash and zsh
filetypes = { "bash", "zsh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})
-- Shell (POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use POSIX
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "posix" },
-- Restrict to POSIX sh
filetypes = { "sh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})

View file

@ -12,8 +12,7 @@ let
movementKeys = [ "Left" "Down" "Up" "Right" ]; movementKeys = [ "Left" "Down" "Up" "Right" ];
vimMovementKeys = [ "h" "j" "k" "l" ]; vimMovementKeys = [ "h" "j" "k" "l" ];
shutdownMode = shutdownMode =
"(l)ock, (e)xit, switch_(u)ser, (h)ibernate, (r)eboot, (Shift+s)hutdown"; "(l)ock, (e)xit, switch_(u)ser, (h)ibernate, (r)eboot, (Shift+s)hutdown"; # spellchecker:disable-line
# Takes an attrset of bindings for movement keys, transforms it to Vim keys # Takes an attrset of bindings for movement keys, transforms it to Vim keys
toVimKeyBindings = toVimKeyBindings =
let let
@ -127,10 +126,9 @@ in
{ class = "^Blueman-.*$"; } { class = "^Blueman-.*$"; }
{ title = "^htop$"; } { title = "^htop$"; }
{ class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; } { class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; }
{ class = "^pavucontrol.*$"; } { class = "^Pavucontrol.*$"; }
{ class = "^Arandr$"; } { class = "^Arandr$"; }
{ class = "^\\.blueman-manager-wrapped$"; } { class = ".?blueman-manager.*$"; }
{ class = "^\\.arandr-wrapped$"; }
]; ];
}; };
@ -372,7 +370,8 @@ in
}; };
startup = [ startup = [
# NOTE: rely on systemd user services instead... # FIXME
# { commdand; always; notification; }
]; ];
window = { window = {

View file

@ -49,7 +49,7 @@ in
}) })
(lib.optionalAttrs config.my.home.bluetooth.enable { (lib.optionalAttrs config.my.home.bluetooth.enable {
block = "bluetooth"; block = "bluetooth";
mac = "F7:78:BA:76:52:F7"; mac = "F7:78:BA:76:52:F7"; # spellchecker:disable-line
format = " $icon MX Ergo{ $percentage|} "; format = " $icon MX Ergo{ $percentage|} ";
disconnected_format = ""; disconnected_format = "";
}) })

View file

@ -30,10 +30,11 @@ in
}; };
# A tidy home is a tidy mind # A tidy home is a tidy mind
dataFile = { dataFile = {
"tig/.keep".text = ""; # `tig` uses `XDG_DATA_HOME` specifically... "bash/.keep".text = "";
"gdb/.keep".text = "";
"tig/.keep".text = "";
}; };
stateFile = { stateFile = {
"bash/.keep".text = "";
"python/.keep".text = ""; "python/.keep".text = "";
}; };
}; };

View file

@ -33,8 +33,9 @@ in
# AMD GPU # AMD GPU
(lib.mkIf (cfg.gpuFlavor == "amd") { (lib.mkIf (cfg.gpuFlavor == "amd") {
boot.initrd.kernelModules = lib.mkIf cfg.amd.enableKernelModule [ "amdgpu" ];
hardware.amdgpu = { hardware.amdgpu = {
initrd.enable = cfg.amd.enableKernelModule;
# Vulkan # Vulkan
amdvlk = lib.mkIf cfg.amd.amdvlk { amdvlk = lib.mkIf cfg.amd.amdvlk {
enable = true; enable = true;

View file

@ -54,6 +54,9 @@ in
# Pulseaudio setup # Pulseaudio setup
(lib.mkIf cfg.pulse.enable { (lib.mkIf cfg.pulse.enable {
# ALSA
sound.enable = true;
hardware.pulseaudio.enable = true; hardware.pulseaudio.enable = true;
}) })
]); ]);

View file

@ -65,7 +65,9 @@ in
aria-rpc = { aria-rpc = {
port = cfg.rpcPort; port = cfg.rpcPort;
# Proxy websockets for RPC # Proxy websockets for RPC
websocketsLocations = [ "/" ]; extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -30,7 +30,9 @@ in
audiobookshelf = { audiobookshelf = {
inherit (cfg) port; inherit (cfg) port;
# Proxy websockets for RPC # Proxy websockets for RPC
websocketsLocations = [ "/" ]; extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -16,7 +16,6 @@
./grocy ./grocy
./indexers ./indexers
./jellyfin ./jellyfin
./komga
./lohr ./lohr
./matrix ./matrix
./mealie ./mealie

View file

@ -27,13 +27,17 @@ in
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
jellyfin = { jellyfin = {
port = 8096; port = 8096;
websocketsLocations = [ "/socket" ];
extraConfig = { extraConfig = {
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
proxy_buffering off; proxy_buffering off;
''; '';
}; };
# Too bad for the repetition...
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
}; };
}; };
}; };

View file

@ -1,55 +0,0 @@
# A Comics/Manga media server
{ config, lib, ... }:
let
cfg = config.my.services.komga;
in
{
options.my.services.komga = with lib; {
enable = mkEnableOption "Komga comics server";
port = mkOption {
type = types.port;
default = 4584;
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.komga = {
enable = true;
inherit (cfg) port;
group = "media";
};
systemd.services.komga.environment = {
LOGGING_LEVEL_ORG_GOTSON_KOMGA = "DEBUG"; # Needed for fail2ban
};
# Set-up media group
users.groups.media = { };
my.services.nginx.virtualHosts = {
komga = {
inherit (cfg) port;
};
};
services.fail2ban.jails = {
komga = ''
enabled = true
filter = komga
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/komga.conf".text = ''
[Definition]
failregex = ^.* ip=<HOST>,.*Bad credentials.*$
journalmatch = _SYSTEMD_UNIT=komga.service
'';
};
};
}

View file

@ -26,6 +26,21 @@ in
description = "Shared secret to register users"; description = "Shared secret to register users";
}; };
slidingSync = {
port = mkOption {
type = types.port;
default = 8009;
example = 8084;
description = "Port used by sliding sync server";
};
secretFile = mkOption {
type = types.str;
example = "/var/lib/matrix/sliding-sync-secret-file.env";
description = "Secret file which contains SYNCV3_SECRET definition";
};
};
mailConfigFile = mkOption { mailConfigFile = mkOption {
type = types.str; type = types.str;
example = "/var/lib/matrix/email-config.yaml"; example = "/var/lib/matrix/email-config.yaml";
@ -91,6 +106,17 @@ in
] ++ lib.optional (cfg.secretFile != null) cfg.secretFile; ] ++ lib.optional (cfg.secretFile != null) cfg.secretFile;
}; };
services.matrix-sliding-sync = {
enable = true;
settings = {
SYNCV3_SERVER = "https://${matrixDomain}";
SYNCV3_BINDADDR = "127.0.0.1:${toString cfg.slidingSync.port}";
};
environmentFile = cfg.slidingSync.secretFile;
};
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
# Element Web app deployment # Element Web app deployment
chat = { chat = {
@ -104,6 +130,9 @@ in
"m.identity_server" = { "m.identity_server" = {
"base_url" = "https://vector.im"; "base_url" = "https://vector.im";
}; };
"org.matrix.msc3575.proxy" = {
"url" = "https://matrix-sync.${domain}";
};
}; };
showLabsSettings = true; showLabsSettings = true;
defaultCountryCode = "FR"; # cocorico defaultCountryCode = "FR"; # cocorico
@ -123,6 +152,10 @@ in
matrix-client = { matrix-client = {
port = clientPort.private; port = clientPort.private;
}; };
# Sliding sync
matrix-sync = {
inherit (cfg.slidingSync) port;
};
}; };
# Those are too complicated to use my wrapper... # Those are too complicated to use my wrapper...
@ -145,6 +178,11 @@ in
"/_matrix" = proxyToClientPort; "/_matrix" = proxyToClientPort;
"/_synapse/client" = proxyToClientPort; "/_synapse/client" = proxyToClientPort;
# Sliding sync
"~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = {
proxyPass = "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}";
};
}; };
listen = [ listen = [
@ -190,6 +228,7 @@ in
client = { client = {
"m.homeserver" = { "base_url" = "https://${matrixDomain}"; }; "m.homeserver" = { "base_url" = "https://${matrixDomain}"; };
"m.identity_server" = { "base_url" = "https://vector.im"; }; "m.identity_server" = { "base_url" = "https://vector.im"; };
"org.matrix.msc3575.proxy" = { "url" = "https://matrix-sync.${domain}"; };
}; };
# ACAO required to allow element-web on any URL to request this json file # ACAO required to allow element-web on any URL to request this json file
in in

View file

@ -1,50 +0,0 @@
# Document editor with Nextcloud
{ config, lib, ... }:
let
cfg = config.my.services.nextcloud.collabora;
in
{
options.my.services.nextcloud.collabora = with lib; {
enable = mkEnableOption "Collabora integration";
port = mkOption {
type = types.port;
default = 9980;
example = 8080;
description = "Internal port for API";
};
};
config = lib.mkIf cfg.enable {
services.collabora-online = {
enable = true;
inherit (cfg) port;
aliasGroups = [
{
host = "https://collabora.${config.networking.domain}";
# Allow using from nextcloud
aliases = [ "https://${config.services.nextcloud.hostName}" ];
}
];
settings = {
# Rely on reverse proxy for SSL
ssl = {
enable = false;
termination = true;
};
};
};
my.services.nginx.virtualHosts = {
collabora = {
inherit (cfg) port;
websocketsLocations = [
"~ ^/cool/(.*)/ws$"
"^~ /cool/adminws"
];
};
};
};
}

View file

@ -4,10 +4,6 @@ let
cfg = config.my.services.nextcloud; cfg = config.my.services.nextcloud;
in in
{ {
imports = [
./collabora.nix
];
options.my.services.nextcloud = with lib; { options.my.services.nextcloud = with lib; {
enable = mkEnableOption "Nextcloud"; enable = mkEnableOption "Nextcloud";
maxSize = mkOption { maxSize = mkOption {
@ -35,7 +31,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
package = pkgs.nextcloud30; package = pkgs.nextcloud29;
hostName = "nextcloud.${config.networking.domain}"; hostName = "nextcloud.${config.networking.domain}";
home = "/var/lib/nextcloud"; home = "/var/lib/nextcloud";
maxUploadSize = cfg.maxSize; maxUploadSize = cfg.maxSize;

View file

@ -17,16 +17,6 @@ let
''; '';
}; };
websocketsLocations = mkOption {
type = with types; listOf str;
default = [ ];
example = [ "/socket" ];
description = ''
Which locations on this virtual host should be configured for
websockets.
'';
};
port = mkOption { port = mkOption {
type = with types; nullOr port; type = with types; nullOr port;
default = null; default = null;
@ -70,13 +60,10 @@ let
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; # FIXME: forward type of virtualHosts type = types.attrs; # FIXME: forward type of virtualHosts
example = { example = {
extraConfig = '' locations."/socket" = {
add_header X-Clacks-Overhead "GNU Terry Pratchett"; proxyPass = "http://127.0.0.1:8096/";
''; proxyWebsockets = true;
};
locations."/".extraConfig = ''
client_max_body_size 1G;
'';
}; };
default = { }; default = { };
description = '' description = ''
@ -87,6 +74,10 @@ let
}); });
in in
{ {
imports = [
./sso
];
options.my.services.nginx = with lib; { options.my.services.nginx = with lib; {
enable = mkEnableOption "Nginx"; enable = mkEnableOption "Nginx";
@ -95,7 +86,7 @@ in
type = types.str; type = types.str;
example = "/var/lib/acme/creds.env"; example = "/var/lib/acme/creds.env";
description = '' description = ''
OVH API key file as an 'EnvironmentFile' (see `systemd.exec(5)`) Gandi API key file as an 'EnvironmentFile' (see `systemd.exec(5)`)
''; '';
}; };
}; };
@ -117,7 +108,12 @@ in
}; };
jellyfin = { jellyfin = {
port = 8096; port = 8096;
websocketsLocations = [ "/socket" ]; extraConfig = {
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
};
}; };
}; };
description = '' description = ''
@ -199,19 +195,6 @@ in
} configured. } configured.
''; '';
})) }))
++ (lib.flip lib.mapAttrsToList cfg.virtualHosts (_: { subdomain, ... } @ args:
let
proxyPass = [ "port" "socket" ];
proxyPassUsed = lib.any (v: args.${v} != null) proxyPass;
in
{
assertion = args.websocketsLocations != [ ] -> proxyPassUsed;
message = ''
Subdomain '${subdomain}' can only use 'websocketsLocations' with one of ${
lib.concatStringsSep ", " (builtins.map (v: "'${v}'") proxyPass)
}.
'';
}))
++ ( ++ (
let let
ports = lib.my.mapFilter ports = lib.my.mapFilter
@ -258,14 +241,6 @@ in
virtualHosts = virtualHosts =
let let
domain = config.networking.domain; domain = config.networking.domain;
mkProxyPass = { websocketsLocations, ... }: proxyPass:
let
websockets = lib.genAttrs websocketsLocations (_: {
inherit proxyPass;
proxyWebsockets = true;
});
in
{ "/" = { inherit proxyPass; }; } // websockets;
mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair
"${subdomain}.${domain}" "${subdomain}.${domain}"
(lib.my.recursiveMerge [ (lib.my.recursiveMerge [
@ -276,7 +251,8 @@ in
} }
# Proxy to port # Proxy to port
(lib.optionalAttrs (args.port != null) { (lib.optionalAttrs (args.port != null) {
locations = mkProxyPass args "http://127.0.0.1:${toString args.port}"; locations."/".proxyPass =
"http://127.0.0.1:${toString args.port}";
}) })
# Serve filesystem content # Serve filesystem content
(lib.optionalAttrs (args.root != null) { (lib.optionalAttrs (args.root != null) {
@ -284,7 +260,8 @@ in
}) })
# Serve to UNIX socket # Serve to UNIX socket
(lib.optionalAttrs (args.socket != null) { (lib.optionalAttrs (args.socket != null) {
locations = mkProxyPass args "http://unix:${args.socket}"; locations."/".proxyPass =
"http://unix:${args.socket}";
}) })
# Redirect to a different domain # Redirect to a different domain
(lib.optionalAttrs (args.redirect != null) { (lib.optionalAttrs (args.redirect != null) {
@ -304,7 +281,6 @@ in
locations."/" = { locations."/" = {
extraConfig = extraConfig =
# FIXME: check that X-User is dropped otherwise
(args.extraConfig.locations."/".extraConfig or "") + '' (args.extraConfig.locations."/".extraConfig or "") + ''
# Use SSO # Use SSO
auth_request /sso-auth; auth_request /sso-auth;
@ -438,8 +414,7 @@ in
{ {
"${domain}" = { "${domain}" = {
extraDomainNames = [ "*.${domain}" ]; extraDomainNames = [ "*.${domain}" ];
dnsProvider = "ovh"; dnsProvider = "gandiv5";
dnsPropagationCheck = false; # OVH is slow
inherit (cfg.acme) credentialsFile; inherit (cfg.acme) credentialsFile;
}; };
}; };

View file

@ -0,0 +1,84 @@
# I must override the module to allow having runtime secrets
{ config, lib, pkgs, utils, ... }:
let
cfg = config.services.nginx.sso;
pkg = lib.getBin cfg.package;
confPath = "/var/lib/nginx-sso/config.json";
in
{
disabledModules = [ "services/security/nginx-sso.nix" ];
options.services.nginx.sso = with lib; {
enable = mkEnableOption "nginx-sso service";
package = mkOption {
type = types.package;
default = pkgs.nginx-sso;
defaultText = "pkgs.nginx-sso";
description = ''
The nginx-sso package that should be used.
'';
};
configuration = mkOption {
type = types.attrsOf types.unspecified;
default = { };
example = literalExample ''
{
listen = { addr = "127.0.0.1"; port = 8080; };
providers.token.tokens = {
myuser = "MyToken";
};
acl = {
rule_sets = [
{
rules = [ { field = "x-application"; equals = "MyApp"; } ];
allow = [ "myuser" ];
}
];
};
}
'';
description = ''
nginx-sso configuration
(<link xlink:href="https://github.com/Luzifer/nginx-sso/wiki/Main-Configuration">documentation</link>)
as a Nix attribute set.
'';
};
};
config = lib.mkIf cfg.enable {
systemd.services.nginx-sso = {
description = "Nginx SSO Backend";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
StateDirectory = "nginx-sso";
WorkingDirectory = "/var/lib/nginx-sso";
# The files to be merged might not have the correct permissions
ExecStartPre = pkgs.writeShellScript "merge-nginx-sso-config" ''
rm -f '${confPath}'
${utils.genJqSecretsReplacementSnippet cfg.configuration confPath}
'';
ExecStart = lib.mkForce ''
${lib.getExe pkg} \
--config ${confPath} \
--frontend-dir ${pkg}/share/frontend
'';
Restart = "always";
User = "nginx-sso";
Group = "nginx-sso";
};
};
users.users.nginx-sso = {
isSystemUser = true;
group = "nginx-sso";
};
users.groups.nginx-sso = { };
};
}

View file

@ -1,4 +1,4 @@
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.my.services.paperless; cfg = config.my.services.paperless;
in in
@ -61,6 +61,11 @@ in
PAPERLESS_ENABLE_HTTP_REMOTE_USER = true; PAPERLESS_ENABLE_HTTP_REMOTE_USER = true;
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER"; PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER";
# Use PostgreSQL
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_DBUSER = "paperless";
PAPERLESS_DBNAME = "paperless";
# Security settings # Security settings
PAPERLESS_ALLOWED_HOSTS = paperlessDomain; PAPERLESS_ALLOWED_HOSTS = paperlessDomain;
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}"; PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}";
@ -75,18 +80,63 @@ in
# Misc # Misc
PAPERLESS_TIME_ZONE = config.time.timeZone; PAPERLESS_TIME_ZONE = config.time.timeZone;
PAPERLESS_ADMIN_USER = cfg.username; PAPERLESS_ADMIN_USER = cfg.username;
# Fix classifier hangs
LD_LIBRARY_PATH = "${lib.getLib pkgs.mkl}/lib";
}; };
# Admin password # Admin password
passwordFile = cfg.passwordFile; passwordFile = cfg.passwordFile;
};
# Secret key systemd.services = {
environmentFile = cfg.secretKeyFile; paperless-scheduler = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
# Automatic PostgreSQL provisioning serviceConfig = {
database = { EnvironmentFile = cfg.secretKeyFile;
createLocally = true; };
}; };
paperless-consumer = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-web = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-task-queue = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
};
# Set-up database
services.postgresql = {
enable = true;
ensureDatabases = [ "paperless" ];
ensureUsers = [
{
name = "paperless";
ensureDBOwnership = true;
}
];
}; };
# Set-up media group # Set-up media group
@ -102,7 +152,11 @@ in
sso = { sso = {
enable = true; enable = true;
}; };
websocketsLocations = [ "/" ];
# Enable websockets on root
extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -14,7 +14,7 @@ in
# Let other services enable postgres when they need it # Let other services enable postgres when they need it
(lib.mkIf cfg.enable { (lib.mkIf cfg.enable {
services.postgresql = { services.postgresql = {
package = pkgs.postgresql_17; package = pkgs.postgresql_13;
}; };
}) })
@ -23,15 +23,15 @@ in
environment.systemPackages = environment.systemPackages =
let let
pgCfg = config.services.postgresql; pgCfg = config.services.postgresql;
newPackage' = pkgs.postgresql_17; newPackage' = pkgs.postgresql_13;
oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package; oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package;
oldData = pgCfg.dataDir; oldData = pgCfg.dataDir;
oldBin = "${if pgCfg.extensions == [] then oldPackage else oldPackage.withPackages pgCfg.extensions}/bin"; oldBin = "${if pgCfg.extraPlugins == [] then oldPackage else oldPackage.withPackages pgCfg.extraPlugins}/bin";
newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage'; newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage';
newData = "/var/lib/postgresql/${newPackage.psqlSchema}"; newData = "/var/lib/postgresql/${newPackage.psqlSchema}";
newBin = "${if pgCfg.extensions == [] then newPackage else newPackage.withPackages pgCfg.extensions}/bin"; newBin = "${if pgCfg.extraPlugins == [] then newPackage else newPackage.withPackages pgCfg.extraPlugins}/bin";
in in
[ [
(pkgs.writeScriptBin "upgrade-pg-cluster" '' (pkgs.writeScriptBin "upgrade-pg-cluster" ''

View file

@ -53,20 +53,6 @@ in
}; };
}; };
services.fail2ban.jails = { # FIXME: fail2ban
pyload = ''
enabled = true
filter = pyload
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/pyload.conf".text = ''
[Definition]
failregex = ^.*Login failed for user '<F-USER>.*</F-USER>' \[CLIENT: <HOST>\]$
journalmatch = _SYSTEMD_UNIT=pyload.service
'';
};
}; };
} }

View file

@ -96,15 +96,5 @@ in
# Sonarr for shows # Sonarr for shows
(mkFullConfig "sonarr") (mkFullConfig "sonarr")
(mkFail2Ban "sonarr") (mkFail2Ban "sonarr")
# HACK: until https://github.com/NixOS/nixpkgs/issues/360592 is resolved
(lib.mkIf cfg.sonarr.enable {
nixpkgs.config.permittedInsecurePackages = [
"aspnetcore-runtime-6.0.36"
"aspnetcore-runtime-wrapped-6.0.36"
"dotnet-sdk-6.0.428"
"dotnet-sdk-wrapped-6.0.428"
];
})
]); ]);
} }

View file

@ -22,10 +22,6 @@ in
options.my.system.nix = with lib; { options.my.system.nix = with lib; {
enable = my.mkDisableOption "nix configuration"; enable = my.mkDisableOption "nix configuration";
gc = {
enable = my.mkDisableOption "nix GC configuration";
};
cache = { cache = {
selfHosted = my.mkDisableOption "self-hosted cache"; selfHosted = my.mkDisableOption "self-hosted cache";
}; };
@ -66,22 +62,6 @@ in
}; };
} }
(lib.mkIf cfg.gc.enable {
nix.gc = {
automatic = true;
# Every week, with some wiggle room
dates = "weekly";
randomizedDelaySec = "10min";
# Use a persistent timer for e.g: laptops
persistent = true;
# Delete old profiles automatically after 15 days
options = "--delete-older-than 15d";
};
})
(lib.mkIf cfg.cache.selfHosted { (lib.mkIf cfg.cache.selfHosted {
nix = { nix = {
settings = { settings = {

View file

@ -1,5 +1,5 @@
# Common packages # Common packages
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.my.system.packages; cfg = config.my.system.packages;
in in
@ -13,6 +13,10 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
wget
];
programs = { programs = {
vim = { vim = {
enable = true; enable = true;

View file

@ -1,4 +0,0 @@
self: prev:
{
vimPlugins = prev.vimPlugins.extend (self.callPackage ./generated.nix { });
}

View file

@ -1,14 +0,0 @@
{ fetchpatch, ... }:
_final: prev: {
lsp-format-nvim = prev.lsp-format-nvim.overrideAttrs (oa: {
patches = (oa.patches or [ ]) ++ [
# https://github.com/lukas-reineke/lsp-format.nvim/issues/94
(fetchpatch {
name = "use-effective-indentation";
url = "https://github.com/liskin/lsp-format.nvim/commit/3757ac443bdf5bd166673833794553229ee8d939.patch";
hash = "sha256-Dv+TvXrU/IrrPxz2MSPbLmRxch+qkHbI3AyFMj/ssDk=";
})
];
});
}

View file

@ -66,7 +66,7 @@ query_password() {
printf '%s\n' "$PASSWORD" printf '%s\n' "$PASSWORD"
} }
if [ $# -lt 1 ] || [ $# -gt 2 ]; then if [ $# -lt 1 ] || [ $# -gt 2 ]; then
usage usage
exit 1 exit 1
fi fi

47
pkgs/cgt-calc/default.nix Normal file
View file

@ -0,0 +1,47 @@
{ lib
, fetchFromGitHub
, python3Packages
, withTeXLive ? true
, texliveSmall
}:
python3Packages.buildPythonApplication rec {
pname = "cgt-calc";
version = "1.13.0";
pyproject = true;
src = fetchFromGitHub {
owner = "KapJI";
repo = "capital-gains-calculator";
rev = "v${version}";
hash = "sha256-y/Y05wG89nccXyxfjqazyPJhd8dOkfwRJre+Rzx97Hw=";
};
build-system = with python3Packages; [
poetry-core
];
dependencies = with python3Packages; [
defusedxml
jinja2
pandas
requests
types-requests
yfinance
];
makeWrapperArgs = lib.optionals withTeXLive [
"--prefix"
"PATH"
":"
"${lib.getBin texliveSmall}/bin"
];
meta = with lib; {
description = "UK capital gains tax calculator";
homepage = "https://github.com/KapJI/capital-gains-calculator";
license = with licenses; [ mit ];
mainProgram = "cgt-calc";
maintainers = with maintainers; [ ambroisie ];
platforms = platforms.unix;
};
}

View file

@ -62,7 +62,7 @@ do_toggle() {
} }
case "$1" in case "$1" in
up | down) up|down)
do_change_volume "$@" do_change_volume "$@"
;; ;;
toggle) toggle)

View file

@ -2,6 +2,8 @@
pkgs.lib.makeScope pkgs.newScope (pkgs: { pkgs.lib.makeScope pkgs.newScope (pkgs: {
bw-pass = pkgs.callPackage ./bw-pass { }; bw-pass = pkgs.callPackage ./bw-pass { };
cgt-calc = pkgs.callPackage ./cgt-calc { };
change-audio = pkgs.callPackage ./change-audio { }; change-audio = pkgs.callPackage ./change-audio { };
change-backlight = pkgs.callPackage ./change-backlight { }; change-backlight = pkgs.callPackage ./change-backlight { };

View file

@ -81,23 +81,23 @@ parse_args() {
shift shift
case "$opt" in case "$opt" in
-h | --help) -h|--help)
usage usage
exit exit
;; ;;
-f | --flake-output) -f|--flake-output)
FLAKE_OUTPUTS+=("$1") FLAKE_OUTPUTS+=("$1")
shift shift
;; ;;
-o | --output) -o|--output)
OUTPUT_FILE="$1" OUTPUT_FILE="$1"
shift shift
;; ;;
-n | --new-rev) -n|--new-rev)
NEW_REV="$(git rev-parse "$1")" NEW_REV="$(git rev-parse "$1")"
shift shift
;; ;;
-p | --previous-rev) -p|--previous-rev)
PREVIOUS_REV="$(git rev-parse "$1")" PREVIOUS_REV="$(git rev-parse "$1")"
shift shift
;; ;;
@ -157,7 +157,7 @@ list_dev_shells() {
} }
diff_output() { diff_output() {
local PREV NEW local PREV NEW;
PREV="$(mktemp --dry-run)" PREV="$(mktemp --dry-run)"
NEW="$(mktemp --dry-run)" NEW="$(mktemp --dry-run)"
@ -169,7 +169,7 @@ diff_output() {
printf 'Closure diff for `%s`:\n```\n' "$1" printf 'Closure diff for `%s`:\n```\n' "$1"
nix store diff-closures "$PREV" "$NEW" | sanitize_output nix store diff-closures "$PREV" "$NEW" | sanitize_output
printf '```\n\n' printf '```\n\n'
} >>"$OUTPUT_FILE" } >> "$OUTPUT_FILE"
} }
parse_args "$@" parse_args "$@"

View file

@ -15,7 +15,7 @@ usage() {
exec 1>&2 exec 1>&2
fi fi
cat <<EOF cat << EOF
Usage: $0 [options] [string] Usage: $0 [options] [string]
Send an arbitrary string to the terminal clipboard using the OSC 52 escape Send an arbitrary string to the terminal clipboard using the OSC 52 escape
sequence as specified in xterm: sequence as specified in xterm:

View file

@ -13,7 +13,7 @@ usage() {
exec 1>&2 exec 1>&2
fi fi
cat <<EOF cat << EOF
Usage: $0 [options] <title> <message> Usage: $0 [options] <title> <message>
Send a notification (title and message) to the host system using the OSC 777 Send a notification (title and message) to the host system using the OSC 777
escape sequence: escape sequence: