Skip to content

Instantly share code, notes, and snippets.

@istudyatuni
Last active October 1, 2024 20:21
Show Gist options
  • Save istudyatuni/f65c162350902daa9d9d01a057806f47 to your computer and use it in GitHub Desktop.
Save istudyatuni/f65c162350902daa9d9d01a057806f47 to your computer and use it in GitHub Desktop.
Generate rustic config with nix. Also contains workaround for globs not working as expected
# home-manager module
{lib, pkgs, ...}: let
user = "you";
toTOML = name: data: (pkgs.formats.toml {}).generate name data;
# all paths should be without trailing slashes
simpleSource = path: tags: {
source = path; # todo (v0.9): rename to sources and make list
tag = tags; # todo (v0.9): rename to tags
};
simpleHomeSource = path: simpleSource "/home/${user}/${path}";
simpleHomeGitSource = path: tags: (simpleHomeSource path tags) // {no-require-git = false;};
# unlike "simple" functions above can handle globs
homeSourceFunc = confFunc: path: tags: {
# insert "!*" to exlude all by default
exclude-all ? false,
exclude ? [],
include ? [],
}: let
conf = confFunc path tags;
f = prefix: path: "${prefix}${conf.source}/${path}";
globs = builtins.concatLists [
(lib.optionals exclude-all ["!*"])
(map (i: f "" i) include)
(map (e: f "!" e) exclude)
];
in
conf // {glob = globs;}; # todo (v0.9): rename to globs
homeSource = homeSourceFunc simpleHomeSource;
fullSource = homeSourceFunc simpleSource;
# workaround for glob. see https://github.com/rustic-rs/rustic/issues/1151
mergeGlobImpl = list: map (g: g.path + lib.optionalString g.recursive "/**/*") (builtins.concatLists list);
mergeGlob = list: lib.lists.unique (lib.naturalSort (mergeGlobImpl list));
# "a/b/c" -> ["a" "a/b" "a/b/c"]
pathIncreasing = path: let
comp = lib.path.subpath.components path;
in
(lib.foldl (state: e: rec {
cur = "${state.cur}/${e}";
acc = lib.flatten [state.acc [cur]];
}) rec {
cur = builtins.head comp;
acc = [cur];
} (lib.drop 1 comp))
.acc;
# build for mergeGlob
parec = path: recursive: {
inherit path;
inherit recursive;
};
pathNoRec = path: [(parec path false)];
dirExclude = pathNoRec; # use in exclude
dir = path:
lib.flatten [
(map pathNoRec (pathIncreasing path)) # build dirs up to path without /**/*
(parec path true)
];
# build directories where file live
file = path: map pathNoRec (pathIncreasing path);
in {
home.file.".config/rustic/rustic.toml".source = toTOML "rustic.toml" {
# global = {
# log-level = "debug";
# log-file = "/log/rustic.log";
# dry-run = true;
# };
repository = {
repository = "/path/to/repo";
# password = "...";
no-cache = true;
};
# snapshot-filter options: These options apply to all commands that use snapshot filters
# snapshot-filter = {
# filter-host = ["myhost"];
# };
backup = {
git-ignore = true;
no-require-git = true;
exclude-if-present = [".nobackup" "CACHEDIR.TAG"];
# todo (v0.9): rename to globs
glob = [
"!/**/.git/**/hooks/*.sample"
];
one-file-system = true;
skip-identical-parent = true;
# todo (v0.9): rename to snapshots
# all sources are just examples
sources = [
(simpleHomeSource "Pictures" ["pictures"])
(homeSource "Doc" ["doc"] {
exclude = [
"Work"
];
})
(homeSource ".config" ["dotfiles"] {
exclude-all = true;
include = mergeGlob [
(dir "nvim")
(dir "rustic")
];
exclude = let
dir = dirExclude;
in
mergeGlob [
(dir "nvim/plugin")
(file "rustic/rustic.toml")
];
})
(fullSource "/home/${user}" ["keys" "dotfiles"] {
exclude-all = true;
include = mergeGlob [
(dir ".ssh")
(file ".zsh_history")
(file ".zshrc")
];
})
];
};
forget = {
keep-hourly = 1;
keep-daily = 2;
keep-weekly = 2;
keep-monthly = 4;
keep-yearly = 10;
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment