Compare commits

...
5 Commits
Author SHA1 Message Date
hektor b2bd384d0e refactor(git): nixify
check / lint (push) Successful in 14s
2026-09-27 23:31:51 +02:00
hektor 28ebd62e33 refactor(taskwarrior): nixify 2026-09-27 23:31:51 +02:00
hektor 7acff57575 refactor(k8s): move module options to 'default.nix' 2026-09-27 23:31:51 +02:00
hektor e0ff23879f refactor(git): move module options to 'default.nix' 2026-09-27 23:31:00 +02:00
hektor f530dfea50 feat(home): add Gitea CLI 2026-09-27 20:59:21 +02:00
29 changed files with 340 additions and 305 deletions

No files matched your search

-2
View File
@@ -1,2 +0,0 @@
taskrc.d/sync
taskrc.d/private
-13
View File
@@ -1,13 +0,0 @@
include ./taskrc.d/aliases
include ./taskrc.d/urgency
include ./taskrc.d/reports
include ./taskrc.d/contexts
include ./taskrc.d/colors
include ./taskrc.d/udas
search.case.sensitive=no
rc.json.array=on
rc.verbose=nothing
news.version=3.4.2
-4
View File
@@ -1,4 +0,0 @@
alias.burndown=burndown.daily
alias.a=add
alias.rm=delete
alias.e=modify
-12
View File
@@ -1,12 +0,0 @@
color.active=bold white on black
color.alternate=
color.scheduled=
color.until=
color.blocking=bold
color.blocked=gray15
color.uda.priority.H=bold
color.uda.priority.M=
color.uda.priority.L=
color.due=
color.due.today=
color.overdue=
-5
View File
@@ -1,5 +0,0 @@
context.home.read=project:home
context.work.read=tags:work
context.home.write=project:home
context.studies.read=project:studies
context.studies.write=project:studies
-4
View File
@@ -1,4 +0,0 @@
include /usr/share/doc/task/rc/light-256.theme
include ./locations
include ./sync
-2
View File
@@ -1,2 +0,0 @@
data.location=$XDG_DATA_HOME/task/
hooks.location=$XDG_DATA_HOME/task/hooks
-24
View File
@@ -1,24 +0,0 @@
# The default report is `next`, to obtain details on a report
# (e.g. the columns used), the following command can be used:
#
# `task _get rc.report.<report_name>.columns`
report.next.columns=id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description
report.next.labels=ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description
report.next.filter=status:pending -WAITING -BLOCKED limit:page
report.in.columns=id,description
report.in.labels=ID,Description
report.in.description=Inbox (untagged)
report.in.filter=status:pending tags.none:
report.in.sort=entry+
report.recent.columns=id,description,entry
report.recent.labels=ID,Description,Age
report.recent.description=Recently added
report.recent.sort=entry+
report.minimal.columns=id,description
report.minimal.labels=,
# verbose=blank,header,footnote,label,new-id,affected,edit,special,project,unwait
-3
View File
@@ -1,3 +0,0 @@
sync.server.url=
sync.server.client_id=
sync.encryption_secret=
-2
View File
@@ -1,2 +0,0 @@
uda.url.type=string
uda.url.label=URL
-9
View File
@@ -1,9 +0,0 @@
urgency.uda.priority.L.coefficient=-1.0
urgency.user.project.studies.coefficient=1.0
urgency.user.project.admin.coefficient=1.0
urgency.user.project.personal.coefficient=0.5
urgency.user.project.groceries.coefficient=0.5
urgency.user.project.home.coefficient=0.2
urgency.user.project.creative.coefficient=0.0
urgency.user.project.side.coefficient=0.0
-104
View File
@@ -1,104 +0,0 @@
[include]
path = ~/.gitconfig.email
[core]
editor = nvim
excludesfile = ~/.gitignore
[user]
name = Hektor Misplon
username = hektor
signingKey = AEB98353B8D72E465C4236435151AF79E723F21C
[alias]
d = diff
ds = diff --staged
a = add
ap = add -p
c = commit
cm = commit -m
cam = commit --amend
l = log --pretty=format:"(%an)\\ \\ %h\\ \\ %ad\\ \\ %s" --date=short
s = status --short
sv = status --verbose
co = checkout
cob = checkout -b
pullr = "pull --rebase --autostash"
pushf = "push --force-with-lease"
# Note these follow the naming convention of my `.bash_aliases`
al = "!git config -l | grep alias | cut -c 7-"
alf = "!git config -l | grep alias | cut -c 7- | fzf"
al- = "!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)"
rs = "restore --staged"
rb = "rebase"
rbi = "rebase -i"
wt = "worktree"
wtc = "config remote.origin.fetch \"+refs/heads/*:refs/remotes/origin/*\""
[color]
ui = auto
[color "diff"]
meta = yellow bold
commit = green bold
frag = magenta bold
old = red bold
new = green bold
whitespace = red reverse
[color "diff-highlight"]
oldNormal = red bold
oldHighlight = "red bold 52"
newNormal = "green bold"
newHighlight = "green bold 22"
[color "branch"]
current = normal bold
local = normal
remote = normal italic
[color "status"]
added = green
changed = yellow
untracked = normal italic
[credential]
helper = cache --timeout=3600
[init]
defaultBranch = main
[log]
date = relative
abbrevCommit = true
[credential "https://github.com"]
helper = !gh auth git-credential
[merge]
tool = nvimdiff
conflictstyle = diff3
[diff]
colorMoved = zebra
tool = nvimdiff
[difftool]
prompt = false
[mergetool]
prompt = false
keepBackup = false
[commit]
gpgsign = false
[interactive]
singleKey = true
[pull]
rebase = true
[rerere]
enabled = true
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig.work
[includeIf "gitdir:~/nix-dev-shells/"]
path = ~/.gitconfig.work
-2
View File
@@ -1,2 +0,0 @@
[user]
email = your.email@example.com
-13
View File
@@ -1,13 +0,0 @@
[include]
path = ~/.gitconfig.work.email
[core]
longpaths = true
[user]
name = Hektor Misplon
username = hektor.misplon
signingKey = 1C88BE828184CEE6
[commit]
gpgsign = false
-2
View File
@@ -1,2 +0,0 @@
[user]
email = your.work.email@example.com
@@ -1,32 +0,0 @@
#!/usr/bin/env python3
# Source: <https://gist.github.com/danmou/83079feac22307813178d7f8c456c544>
# This hooks script syncs task warrior to the configured task server without blocking.
# The on-exit event is triggered once, after all processing is complete.
# Make sure hooks are enabled and this hook script is executable.
# Run `task diag` for diagnostics on the hook.
import json
import subprocess
import sys
try:
tasks = json.loads(sys.stdin.readline())
except:
# No input
pass
# Call the `sync` command
# hooks=0 ensures that the sync command doesn't call the on-exit hook
# verbose=nothing sets the verbosity to print nothing at all
ps_1 = subprocess.Popen(
["task", "rc.hooks=0", "sync"],
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
sys.exit(0)
@@ -1,12 +0,0 @@
#!/usr/bin/env bash
# Redirect both stdout and stderr to notify-send as is, but set
# urgency to critical if the command fails
output="$(task rc.hooks=0 sync 2>&1)"
ret=$?
if [ $ret -ne 0 ]; then
urgency=critical
else
urgency=normal
fi
notify-send -u $urgency "Taskwarrior sync" "$output"
+5 -2
View File
@@ -37,8 +37,11 @@
devenv.enable = true; devenv.enable = true;
direnv.enable = true; direnv.enable = true;
gaming.enable = true; gaming.enable = true;
git.enable = true; git = {
git.github.enable = true; enable = true;
gitea.enable = true;
github.enable = true;
};
k8s.k9s.enable = true; k8s.k9s.enable = true;
keepassxc.enable = true; keepassxc.enable = true;
music.enable = true; music.enable = true;
+5 -2
View File
@@ -35,8 +35,11 @@
desktop.niri.enable = true; desktop.niri.enable = true;
devenv.enable = true; devenv.enable = true;
direnv.enable = true; direnv.enable = true;
git.enable = true; git = {
git.github.enable = true; enable = true;
gitea.enable = true;
github.enable = true;
};
k8s.k9s.enable = true; k8s.k9s.enable = true;
keepassxc.enable = true; keepassxc.enable = true;
music.enable = true; music.enable = true;
+163 -12
View File
@@ -1,33 +1,184 @@
{ {
config, config,
inputs,
lib, lib,
pkgs, myUtils,
dotsPath, osConfig ? null,
... ...
}: }:
let
cfg = config.git;
sops = myUtils.sopsAvailability config osConfig;
standalone = osConfig == null;
personalEmail = sops.templates.".gitconfig.email".path;
workEmail = sops.templates.".gitconfig.work.email".path;
workSettings = {
include.path = workEmail;
core.longpaths = true;
user = {
name = "Hektor Misplon";
username = "hektor.misplon";
signingKey = "1C88BE828184CEE6";
};
commit.gpgSign = false;
};
in
{ {
options.git = { options.git = {
enable = lib.mkEnableOption "git"; enable = lib.mkEnableOption "git";
github.enable = lib.mkEnableOption "Github CLI";
gitlab.enable = lib.mkEnableOption "Gitlab CLI"; gitea = {
enable = lib.mkEnableOption "Gitea CLI";
};
github = {
enable = lib.mkEnableOption "Github CLI";
};
gitlab = {
enable = lib.mkEnableOption "Gitlab CLI";
};
}; };
config = lib.mkIf config.git.enable { imports = [
./gitea.nix
./github.nix
./gitlab.nix
];
config = lib.mkIf cfg.enable (
lib.optionalAttrs standalone {
sops = {
secrets = myUtils.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" {
email = [
"personal"
"work"
];
};
templates = {
".gitconfig.email".content = ''
[user]
email = ${config.sops.placeholder."email/personal"}
'';
".gitconfig.work.email".content = ''
[user]
email = ${config.sops.placeholder."email/work"}
'';
};
};
}
// {
assertions = [ assertions = [
{ {
assertion = config.nvim.enable; assertion = config.nvim.enable;
message = "git module requires 'nvim' module (`nvimdiff`)"; message = "git module requires 'nvim' module (`nvimdiff`)";
} }
]; ];
programs.git.enable = true;
home.file = { xdg.configFile."git/ignore".source = ./global.gitignore;
".gitconfig".source = dotsPath + "/.gitconfig";
".gitconfig.work".source = dotsPath + "/.gitconfig.work"; programs.git = {
".gitignore".source = dotsPath + "/.gitignore"; enable = true;
settings = {
core.editor = "nvim";
user = {
name = "Hektor Misplon";
username = "hektor";
signingKey = "AEB98353B8D72E465C4236435151AF79E723F21C";
};
alias = {
d = "diff";
ds = "diff --staged";
a = "add";
ap = "add -p";
c = "commit";
cm = "commit -m";
cam = "commit --amend";
l = ''log --pretty=format:(%an)\ \ %h\ \ %ad\ \ %s --date=short'';
s = "status --short";
sv = "status --verbose";
co = "checkout";
cob = "checkout -b";
pullr = "pull --rebase --autostash";
pushf = "push --force-with-lease";
al = "!git config -l | grep alias | cut -c 7-";
alf = "!git config -l | grep alias | cut -c 7- | fzf";
"al-" =
''!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)'';
rs = "restore --staged";
rb = "rebase";
rbi = "rebase -i";
wt = "worktree";
wtc = ''config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"'';
};
color = {
ui = "auto";
diff = {
meta = "yellow bold";
commit = "green bold";
frag = "magenta bold";
old = "red bold";
new = "green bold";
whitespace = "red reverse";
};
"diff-highlight" = {
oldNormal = "red bold";
oldHighlight = "red bold 52";
newNormal = "green bold";
newHighlight = "green bold 22";
};
branch = {
current = "normal bold";
local = "normal";
remote = "normal italic";
};
status = {
added = "green";
changed = "yellow";
untracked = "normal italic";
};
};
credential.helper = "cache --timeout=3600";
init.defaultBranch = "main";
log = {
date = "relative";
abbrevCommit = true;
};
merge = {
tool = "nvimdiff";
conflictStyle = "diff3";
};
diff = {
colorMoved = "zebra";
tool = "nvimdiff";
};
difftool.prompt = false;
mergetool = {
prompt = false;
keepBackup = false;
};
commit.gpgSign = false;
interactive.singleKey = true;
pull.rebase = true;
rerere.enabled = true;
}; };
programs.gh.enable = config.git.github.enable; includes = [
home.packages = lib.optionals config.git.gitlab.enable [ pkgs.glab ]; { path = personalEmail; }
{
condition = "gitdir:~/work/";
contents = workSettings;
contentSuffix = "gitconfig-work";
}
{
condition = "gitdir:~/nix-dev-shells/";
contents = workSettings;
contentSuffix = "gitconfig-work";
}
];
}; };
}
);
} }
+12
View File
@@ -0,0 +1,12 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkIf (config.git.enable && config.git.gitea.enable) {
home.packages = with pkgs; [ tea ];
};
}
+11
View File
@@ -0,0 +1,11 @@
{
config,
lib,
...
}:
{
config = lib.mkIf (config.git.enable && config.git.github.enable) {
programs.gh.enable = true;
};
}
+12
View File
@@ -0,0 +1,12 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkIf (config.git.enable && config.git.gitlab.enable) {
home.packages = with pkgs; [ glab ];
};
}
File renamed without changes.
+11 -2
View File
@@ -9,13 +9,22 @@ let
cfg = config.k8s; cfg = config.k8s;
in in
{ {
options.k8s = {
enable = lib.mkEnableOption "k8s";
helm = {
enable = lib.mkEnableOption "helm";
};
k9s = {
enable = lib.mkEnableOption "k9s";
};
};
imports = [ imports = [
./helm.nix ./helm.nix
./k9s.nix ./k9s.nix
]; ];
options.k8s.enable = lib.mkEnableOption "k8s";
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
k8s.helm.enable = lib.mkDefault true; k8s.helm.enable = lib.mkDefault true;
k8s.k9s.enable = lib.mkDefault true; k8s.k9s.enable = lib.mkDefault true;
+1 -6
View File
@@ -5,13 +5,8 @@
... ...
}: }:
let
cfg = config.k8s.helm;
in
{ {
options.k8s.helm.enable = lib.mkEnableOption "helm"; config = lib.mkIf config.k8s.helm.enable {
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
(wrapHelm kubernetes-helm { (wrapHelm kubernetes-helm {
plugins = with kubernetes-helmPlugins; [ plugins = with kubernetes-helmPlugins; [
+1 -6
View File
@@ -4,13 +4,8 @@
... ...
}: }:
let
cfg = config.k8s.k9s;
in
{ {
options.k8s.k9s.enable = lib.mkEnableOption "k9s"; config = lib.mkIf config.k8s.k9s.enable {
config = lib.mkIf cfg.enable {
programs.k9s = { programs.k9s = {
enable = true; enable = true;
settings.k9s = { settings.k9s = {
+119 -28
View File
@@ -2,7 +2,6 @@
config, config,
lib, lib,
pkgs, pkgs,
dotsPath,
myUtils, myUtils,
osConfig ? null, osConfig ? null,
inputs ? null, inputs ? null,
@@ -13,6 +12,52 @@ let
cfg = config.taskwarrior; cfg = config.taskwarrior;
sops = myUtils.sopsAvailability config osConfig; sops = myUtils.sopsAvailability config osConfig;
standalone = osConfig == null; standalone = osConfig == null;
syncHook = pkgs.writers.writePython3 "on-exit.sync.py" { flakeIgnore = [ "E501" ]; } ''
# Source: <https://gist.github.com/danmou/83079feac22307813178d7f8c456c544>
# This hook syncs Taskwarrior to the configured task server without blocking.
# The on-exit event is triggered once, after all processing is complete.
import json
import subprocess
import sys
try:
json.loads(sys.stdin.readline())
except json.JSONDecodeError:
# No input
pass
# hooks=0 ensures that the sync command doesn't call the on-exit hook.
# verbose=nothing sets the verbosity to print nothing at all.
subprocess.Popen(
["${lib.getExe pkgs.taskwarrior3}", "rc.hooks=0", "sync"],
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
sys.exit(0)
'';
syncAndNotify = pkgs.writeShellApplication {
name = "sync-and-notify";
runtimeInputs = [
pkgs.libnotify
pkgs.taskwarrior3
];
text = ''
# Redirect both stdout and stderr to notify-send as is, but set
# urgency to critical if the command fails.
if output="$(task rc.hooks=0 sync 2>&1)"; then
urgency=normal
else
urgency=critical
fi
notify-send -u "$urgency" "Taskwarrior sync" "$output"
'';
};
in in
{ {
options.taskwarrior.enable = lib.mkEnableOption "taskwarrior"; options.taskwarrior.enable = lib.mkEnableOption "taskwarrior";
@@ -42,39 +87,85 @@ in
lib.optional (!sops.available) lib.optional (!sops.available)
"taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured."; "taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured.";
home.packages = with pkgs; [ home.packages = [ pkgs.taskopen ];
libnotify
taskopen
python3
];
home.file = { home.file = {
".config/task/taskrc" = { ".config/task/taskrc".text = ''
force = true; include ${config.xdg.configHome}/task/home-manager-taskrc
source = dotsPath + "/.config/task/taskrc"; '';
}; ".local/share/task/hooks/on-exit.sync.py".source = syncHook;
".config/task/taskrc.d/aliases".source = dotsPath + "/.config/task/taskrc.d/aliases"; ".local/share/task/scripts/sync-and-notify.sh".source = lib.getExe syncAndNotify;
".config/task/taskrc.d/colors".source = dotsPath + "/.config/task/taskrc.d/colors";
".config/task/taskrc.d/contexts".source = dotsPath + "/.config/task/taskrc.d/contexts";
".config/task/taskrc.d/reports".source = dotsPath + "/.config/task/taskrc.d/reports";
".config/task/taskrc.d/udas".source = dotsPath + "/.config/task/taskrc.d/udas";
".config/task/taskrc.d/urgency".source = dotsPath + "/.config/task/taskrc.d/urgency";
".local/share/task/hooks/on-exit.sync.py" = {
source = dotsPath + "/.local/share/task/hooks/on-exit.sync.py";
};
".local/share/task/scripts/sync-and-notify.sh" = {
source = dotsPath + "/.local/share/task/scripts/sync-and-notify.sh";
executable = true;
};
}; };
programs.taskwarrior = with pkgs; { programs.taskwarrior = {
enable = true; enable = true;
package = taskwarrior3; package = pkgs.taskwarrior3;
colorTheme = "dark-256"; colorTheme = "dark-256";
config = { config = {
recurrence = "off"; # taskrc.d/aliases
reserved.lines = 3; "alias.a" = "add";
"alias.burndown" = "burndown.daily";
"alias.e" = "modify";
"alias.rm" = "delete";
# taskrc.d/colors
"color.active" = "bold white on black";
"color.alternate" = "";
"color.blocked" = "gray15";
"color.blocking" = "bold";
"color.due" = "";
"color.due.today" = "";
"color.overdue" = "";
"color.scheduled" = "";
"color.uda.priority.H" = "bold";
"color.uda.priority.L" = "";
"color.uda.priority.M" = "";
"color.until" = "";
# taskrc.d/contexts
"context.home.read" = "project:home";
"context.home.write" = "project:home";
"context.studies.read" = "project:studies";
"context.studies.write" = "project:studies";
"context.work.read" = "tags:work";
# taskrc.d/reports
"report.in.columns" = "id,description";
"report.in.description" = "Inbox (untagged)";
"report.in.filter" = "status:pending tags.none:";
"report.in.labels" = "ID,Description";
"report.in.sort" = "entry+";
"report.minimal.columns" = "id,description";
"report.minimal.labels" = ",";
"report.next.columns" =
"id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description";
"report.next.filter" = "status:pending -WAITING -BLOCKED limit:page";
"report.next.labels" = "ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description";
"report.recent.columns" = "id,description,entry";
"report.recent.description" = "Recently added";
"report.recent.labels" = "ID,Description,Age";
"report.recent.sort" = "entry+";
# taskrc.d/udas
"uda.url.label" = "URL";
"uda.url.type" = "string";
# taskrc.d/urgency
"urgency.uda.priority.L.coefficient" = "-1.0";
"urgency.user.project.admin.coefficient" = "1.0";
"urgency.user.project.creative.coefficient" = "0.0";
"urgency.user.project.groceries.coefficient" = "0.5";
"urgency.user.project.home.coefficient" = "0.2";
"urgency.user.project.personal.coefficient" = "0.5";
"urgency.user.project.side.coefficient" = "0.0";
"urgency.user.project.studies.coefficient" = "1.0";
# misc
"news.version" = "3.4.2";
"rc.json.array" = "on";
"rc.verbose" = "nothing";
"search.case.sensitive" = "no";
"recurrence" = "off";
"reserved.lines" = "3";
}; };
extraConfig = lib.optionalString sops.available '' extraConfig = lib.optionalString sops.available ''
include ${sops.templates."taskrc.d/sync".path} include ${sops.templates."taskrc.d/sync".path}
-2
View File
@@ -12,7 +12,6 @@ in
sops.templates = { sops.templates = {
".gitconfig.email" = { ".gitconfig.email" = {
inherit owner; inherit owner;
path = "/home/${username}/.gitconfig.email";
content = '' content = ''
[user] [user]
email = ${config.sops.placeholder."email/personal"} email = ${config.sops.placeholder."email/personal"}
@@ -20,7 +19,6 @@ in
}; };
".gitconfig.work.email" = { ".gitconfig.work.email" = {
inherit owner; inherit owner;
path = "/home/${username}/.gitconfig.work.email";
content = '' content = ''
[user] [user]
email = ${config.sops.placeholder."email/work"} email = ${config.sops.placeholder."email/work"}