diff options
Diffstat (limited to '')
32 files changed, 548 insertions, 138 deletions
diff --git a/hosts/by-name/tiamat/configuration.nix b/hosts/by-name/tiamat/configuration.nix index 462bbe9a..d2bf3473 100644 --- a/hosts/by-name/tiamat/configuration.nix +++ b/hosts/by-name/tiamat/configuration.nix @@ -15,6 +15,8 @@ }: { imports = [ ./hardware.nix + + ../../../modules/common/soispha ]; vhack = { diff --git a/modules/by-name/al/alacritty/module.nix b/modules/by-name/al/alacritty/module.nix index 74b938ec..f7e4629c 100644 --- a/modules/by-name/al/alacritty/module.nix +++ b/modules/by-name/al/alacritty/module.nix @@ -17,7 +17,7 @@ cfg = config.soispha.programs.alacritty; in { options.soispha.programs.alacritty = { - enable = extra_lib.options.mkDefaultEnabled "alacritty"; + enable = lib.mkEnableOption "alacritty"; package = lib.mkPackageOption pkgs "alacritty" {}; }; diff --git a/modules/by-name/au/ausweisapp/module.nix b/modules/by-name/au/ausweisapp/module.nix index ee3e8917..0156989f 100644 --- a/modules/by-name/au/ausweisapp/module.nix +++ b/modules/by-name/au/ausweisapp/module.nix @@ -7,7 +7,7 @@ cfg = config.soispha.programs.ausweisapp; in { options.soispha.programs.ausweisapp = { - enable = extra_lib.options.mkDefaultEnabled "AusweisApp"; + enable = lib.mkEnableOption "AusweisApp"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ca/calibre/module.nix b/modules/by-name/ca/calibre/module.nix index f56c8490..caef8070 100644 --- a/modules/by-name/ca/calibre/module.nix +++ b/modules/by-name/ca/calibre/module.nix @@ -16,7 +16,7 @@ cfg = config.soispha.programs.calibre; in { options.soispha.programs.calibre = { - enable = extra_lib.options.mkDefaultEnabled "calibre"; + enable = lib.mkEnableOption "calibre"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ca/cargo/module.nix b/modules/by-name/ca/cargo/module.nix index a4216020..06fd8a72 100644 --- a/modules/by-name/ca/cargo/module.nix +++ b/modules/by-name/ca/cargo/module.nix @@ -16,7 +16,7 @@ cfg = config.soispha.programs.cargo; in { options.soispha.programs.cargo = { - enable = extra_lib.options.mkDefaultEnabled "cargo"; + enable = lib.mkEnableOption "cargo"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/dc/dconf/module.nix b/modules/by-name/dc/dconf/module.nix index ec055a6f..78d34546 100644 --- a/modules/by-name/dc/dconf/module.nix +++ b/modules/by-name/dc/dconf/module.nix @@ -7,11 +7,22 @@ # # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{...}: { - # needed to make home-manager play nice with some apps. See: - # https://nix-community.github.io/home-manager/index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal - programs.dconf.enable = true; - # FIXME: This should also be parameterized. <2024-05-16> +{ + config, + lib, + ... +}: let + cfg = config.soispha.services.dconf; +in { + options.soispha.services.dconf = { + enable = lib.mkEnableOption "dconf"; + }; + + config = lib.mkIf cfg.enable { + # needed to make home-manager play nice with some apps. See: + # https://nix-community.github.io/home-manager/index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal + programs.dconf.enable = true; + }; } # vim: nolinebreak nowrap textwidth=0 diff --git a/modules/by-name/fo/foot/module.nix b/modules/by-name/fo/foot/module.nix index d0189e21..9e294968 100644 --- a/modules/by-name/fo/foot/module.nix +++ b/modules/by-name/fo/foot/module.nix @@ -14,10 +14,10 @@ pkgs, ... }: let - cfg = config.soispha.foot; + cfg = config.soispha.programs.foot; in { - options.soispha.foot = { - enable = extra_lib.options.mkDefaultEnabled "foot terminal"; + options.soispha.programs.foot = { + enable = lib.mkEnableOption "foot terminal"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/gt/gtk/module.nix b/modules/by-name/gt/gtk/module.nix index cfb000a0..14aeba9a 100644 --- a/modules/by-name/gt/gtk/module.nix +++ b/modules/by-name/gt/gtk/module.nix @@ -20,7 +20,7 @@ homeConfig = config.home-manager.users.soispha; in { options.soispha.gtk = { - enable = extra_lib.options.mkDefaultEnabled "gtk themes"; + enable = lib.mkEnableOption "gtk themes"; }; config.home-manager.users.soispha = lib.mkIf cfg.enable { diff --git a/modules/by-name/hl/lhedger/module.nix b/modules/by-name/hl/hledger/module.nix index 2a9a9e3a..1739b809 100644 --- a/modules/by-name/hl/lhedger/module.nix +++ b/modules/by-name/hl/hledger/module.nix @@ -14,11 +14,11 @@ extra_lib, ... }: let - cfg = config.soispha.hledger; + cfg = config.soispha.programs.hledger; ledgerFile = "${config.home-manager.users.soispha.xdg.dataHome}/hledger/2025.journal"; in { - options.soispha.hledger = { - enable = extra_lib.options.mkDefaultEnabled "hledger"; + options.soispha.programs.hledger = { + enable = lib.mkEnableOption "hledger"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ia/iamb/module.nix b/modules/by-name/ia/iamb/module.nix index ee466d4e..2ee9d9ad 100644 --- a/modules/by-name/ia/iamb/module.nix +++ b/modules/by-name/ia/iamb/module.nix @@ -16,7 +16,7 @@ cfg = config.soispha.programs.iamb; in { options.soispha.programs.iamb = { - enable = extra_lib.options.mkDefaultEnabled "iamb"; + enable = lib.mkEnableOption "iamb"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/im/impermanence/module.nix b/modules/by-name/im/impermanence/module.nix index a0c308d5..97b16d9c 100644 --- a/modules/by-name/im/impermanence/module.nix +++ b/modules/by-name/im/impermanence/module.nix @@ -24,13 +24,19 @@ in { mode = lib.mkOption { type = lib.types.str; }; + group = lib.mkOption { + type = lib.types.str; + }; + user = lib.mkOption { + type = lib.types.str; + }; }; })); description = "The directories to persist"; }; userDirectories = lib.mkOption { - type = lib.types.attrsOf (lib.types.listOf (lib.types.either lib.types.str (lib.types.submodule { + type = lib.types.nullOr (lib.types.attrsOf (lib.types.listOf (lib.types.either lib.types.str (lib.types.submodule { options = { directory = lib.mkOption { type = lib.types.str; @@ -39,8 +45,8 @@ in { type = lib.types.str; }; }; - }))); - default = []; + })))); + default = null; description = "The directories to persist, for each user."; }; }; @@ -54,7 +60,7 @@ in { hideMounts = true; inherit (cfg) directories; - users = userDirectories; + users = lib.mkIf (cfg.userDirectories != null) userDirectories; files = [ "/etc/machine-id" diff --git a/modules/by-name/lu/lutris/module.nix b/modules/by-name/lu/lutris/module.nix index bc0cc04b..ad4a4037 100644 --- a/modules/by-name/lu/lutris/module.nix +++ b/modules/by-name/lu/lutris/module.nix @@ -19,7 +19,7 @@ inherit (config.home-manager.users.soispha.home) homeDirectory; in { options.soispha.programs.lutris = { - enable = extra_lib.options.mkDefaultEnabled "Lutris"; + enable = lib.mkEnableOption "Lutris"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ma/mandb/module.nix b/modules/by-name/ma/mandb/module.nix index a2467070..69f65469 100644 --- a/modules/by-name/ma/mandb/module.nix +++ b/modules/by-name/ma/mandb/module.nix @@ -10,13 +10,12 @@ { config, lib, - extra_lib, ... }: let - cfg = config.soispha.services.mandb; + cfg = config.vhack.services.mandb; in { - options.soispha.services.mandb = { - enable = extra_lib.options.mkDefaultEnabled "mandb"; + options.vhack.services.mandb = { + enable = lib.mkEnableOption "mandb"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/me/mergiraf/module.nix b/modules/by-name/me/mergiraf/module.nix index e1048ca1..4ff94d89 100644 --- a/modules/by-name/me/mergiraf/module.nix +++ b/modules/by-name/me/mergiraf/module.nix @@ -16,7 +16,7 @@ cfg = config.soispha.programs.mergiraf; in { options.soispha.programs.mergiraf = { - enable = extra_lib.options.mkDefaultEnabled "mergiraf"; + enable = lib.mkEnableOption "mergiraf"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/mp/mpdpopm/module.nix b/modules/by-name/mp/mpdpopm/module.nix index 03529095..93bce634 100644 --- a/modules/by-name/mp/mpdpopm/module.nix +++ b/modules/by-name/mp/mpdpopm/module.nix @@ -19,7 +19,7 @@ settingsFormat = pkgs.formats.json {}; in { options.soispha.services.mpdpopm = { - enable = extra_lib.options.mkDefaultEnabled "mpdpopm"; + enable = lib.mkEnableOption "mpdpopm"; settings = lib.mkOption { # Setting this type allows for correct merging behavior diff --git a/modules/by-name/ni/nix/module.nix b/modules/by-name/ni/nix/module.nix index 5fd10541..6e98ecd4 100644 --- a/modules/by-name/ni/nix/module.nix +++ b/modules/by-name/ni/nix/module.nix @@ -56,7 +56,7 @@ cfg = config.soispha.nix; in { options.soispha.nix = { - enable = extra_lib.options.mkDefaultEnabled "nix"; + enable = lib.mkEnableOption "nix"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ni/nixos-option/module.nix b/modules/by-name/ni/nixos-option/module.nix index 3e41bd34..e5cc9f12 100644 --- a/modules/by-name/ni/nixos-option/module.nix +++ b/modules/by-name/ni/nixos-option/module.nix @@ -7,7 +7,7 @@ cfg = config.soispha.programs.nixos-option; in { options.soispha.programs.nixos-option = { - enable = extra_lib.options.mkDefaultEnabled "nixos-option"; + enable = lib.mkEnableOption "nixos-option"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ol/ollama/module.nix b/modules/by-name/ol/ollama/module.nix index ebc1fbf9..38c7321e 100644 --- a/modules/by-name/ol/ollama/module.nix +++ b/modules/by-name/ol/ollama/module.nix @@ -10,6 +10,7 @@ { config, lib, + pkgs, ... }: let cfg = config.soispha.services.ollama; @@ -23,6 +24,8 @@ in { # Set the mode to 700, so that it is private enough for systemd. { directory = "/var/lib/private"; + user = "root"; + group = "root"; mode = "700"; } @@ -36,7 +39,8 @@ in { services.ollama = { enable = true; - acceleration = false; + + package = pkgs.ollama-vulkan; # TODO: This could work for GPU acceleration. <2024-12-20> # acceleration = "rocm"; diff --git a/modules/by-name/op/openssh/module.nix b/modules/by-name/op/openssh/module.nix index e1464338..5b8abca4 100644 --- a/modules/by-name/op/openssh/module.nix +++ b/modules/by-name/op/openssh/module.nix @@ -1,13 +1,12 @@ { config, lib, - extra_lib, ... }: let cfg = config.vhack.openssh; in { options.vhack.openssh = { - enable = extra_lib.options.mkDefaultEnabled "openssh"; + enable = lib.mkEnableOption "openssh"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/pi/pipewire/module.nix b/modules/by-name/pi/pipewire/module.nix index 5bec816d..79456c8f 100644 --- a/modules/by-name/pi/pipewire/module.nix +++ b/modules/by-name/pi/pipewire/module.nix @@ -13,10 +13,10 @@ extra_lib, ... }: let - cfg = config.soispha.pipewire; + cfg = config.soispha.services.pipewire; in { - options.soispha.pipewire = { - enable = extra_lib.options.mkDefaultEnabled "pipewire and wireplumber"; + options.soispha.services.pipewire = { + enable = lib.mkEnableOption "pipewire and wireplumber"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/pl/plymouth/module.nix b/modules/by-name/pl/plymouth/module.nix index f64c9464..8465cd8a 100644 --- a/modules/by-name/pl/plymouth/module.nix +++ b/modules/by-name/pl/plymouth/module.nix @@ -17,7 +17,7 @@ cfg = config.soispha.services.plymouth; in { options.soispha.services.plymouth = { - enable = extra_lib.options.mkDefaultEnabled "plymouth"; + enable = lib.mkEnableOption "plymouth"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/ro/rofi/module.nix b/modules/by-name/ro/rofi/module.nix index b447ca1e..5ac94781 100644 --- a/modules/by-name/ro/rofi/module.nix +++ b/modules/by-name/ro/rofi/module.nix @@ -16,7 +16,7 @@ cfg = config.soispha.programs.rofi; in { options.soispha.programs.rofi = { - enable = extra_lib.options.mkDefaultEnabled "rofi"; + enable = lib.mkEnableOption "rofi"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/si/signal/module.nix b/modules/by-name/si/signal/module.nix index 4506517f..526a952c 100644 --- a/modules/by-name/si/signal/module.nix +++ b/modules/by-name/si/signal/module.nix @@ -4,10 +4,10 @@ extra_lib, ... }: let - cfg = config.soispha.signal; + cfg = config.soispha.programs.signal; in { - options.soispha.signal = { - enable = extra_lib.options.mkDefaultEnabled "signal"; + options.soispha.programs.signal = { + enable = lib.mkEnableOption "signal"; }; config = lib.mkIf cfg.enable { vhack.persist.userDirectories.soispha = [ diff --git a/modules/by-name/so/sound/module.nix b/modules/by-name/so/sound/module.nix index 732a78e2..8b56a50c 100644 --- a/modules/by-name/so/sound/module.nix +++ b/modules/by-name/so/sound/module.nix @@ -13,10 +13,10 @@ lib, ... }: let - cfg = config.soispha.sound; + cfg = config.soispha.services.sound; in { - options.soispha.sound = { - enable = extra_lib.options.mkDefaultEnabled "sound based on pipewire"; + options.soispha.services.sound = { + enable = lib.mkEnableOption "sound based on pipewire"; }; config = lib.mkIf cfg.enable { @@ -28,7 +28,6 @@ in { alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; - jack.enable = true; }; users = { diff --git a/modules/by-name/st/starship/module.nix b/modules/by-name/st/starship/module.nix index 903f97b6..c6b050ac 100644 --- a/modules/by-name/st/starship/module.nix +++ b/modules/by-name/st/starship/module.nix @@ -17,7 +17,7 @@ cfg = config.soispha.programs.starship; in { options.soispha.programs.starship = { - enable = extra_lib.options.mkDefaultEnabled "starship"; + enable = lib.mkEnableOption "starship"; showBattery = lib.mkOption { type = lib.types.bool; diff --git a/modules/by-name/sw/swaybg/module.nix b/modules/by-name/sw/swaybg/module.nix index 216a0c59..03a82b6f 100644 --- a/modules/by-name/sw/swaybg/module.nix +++ b/modules/by-name/sw/swaybg/module.nix @@ -17,7 +17,7 @@ cfg = config.soispha.programs.swaybg; in { options.soispha.programs.swaybg = { - enable = extra_lib.options.mkDefaultEnabled "swaybg"; + enable = lib.mkEnableOption "swaybg"; }; config = lib.mkIf cfg.enable { diff --git a/modules/by-name/sw/swayidle/module.nix b/modules/by-name/sw/swayidle/module.nix index 953ec83f..a1eb48ba 100644 --- a/modules/by-name/sw/swayidle/module.nix +++ b/modules/by-name/sw/swayidle/module.nix @@ -18,7 +18,7 @@ swaylock = lib.getExe pkgs.swaylock; in { options.soispha.programs.swayidle = { - enable = extra_lib.options.mkDefaultEnabled "swayidle"; + enable = lib.mkEnableOption "swayidle"; }; config = lib.mkIf cfg.enable { diff --git a/modules/common/soispha/default.nix b/modules/common/soispha/default.nix index 99970929..640c6e2f 100644 --- a/modules/common/soispha/default.nix +++ b/modules/common/soispha/default.nix @@ -15,8 +15,6 @@ lib, ... }: { - # TODO(@bpeetz): Move this file to default options in their respective modules. <2025-05-31> - home-manager.users.soispha.home = { username = "soispha"; homeDirectory = config.users.users.soispha.home; @@ -25,6 +23,7 @@ }; vhack = { + openssh.enable = true; persist = { enable = true; @@ -34,43 +33,32 @@ "/var/log" ]; }; - - services.backup = { - storagebox = { - enable = true; - user = "u459143-sub1"; - sshHostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs"; - repositoryPassword = - ../../../hosts/by-name/apzu/secrets/storagebox/repository_password.age; - sshKey = ../../../hosts/by-name/apzu/secrets/storagebox/ssh_key.age; - }; - local = { - enable = true; - repositoryPassword = ../../../hosts/by-name/apzu/secrets/local/repository_password.age; + services = { + mandb.enable = true; + backup = { + storagebox = { + enable = true; + user = "u459143-sub1"; + sshHostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs"; + repositoryPassword = + ../../../hosts/by-name/apzu/secrets/storagebox/repository_password.age; + sshKey = ../../../hosts/by-name/apzu/secrets/storagebox/ssh_key.age; + }; + local = { + enable = true; + repositoryPassword = ../../../hosts/by-name/apzu/secrets/local/repository_password.age; + }; }; }; }; soispha = { - age.enable = true; - boot.enable = true; - cleanup.enable = true; - documentation.enable = true; + services = { + mpdpopm.enable = true; + dconf.enable = true; - fonts = { - enable = true; - enableEmoji = true; - }; + ollama.enable = false; - hardware = { - enable = lib.mkDefault true; - }; - home-manager.enable = true; - - polkit.enable = true; - xdg.enable = true; - - services = { adb = { enable = true; user = "soispha"; @@ -127,9 +115,29 @@ "~/repos" ]; }; - }; + pipewire.enable = true; + plymouth.enable = true; + sound.enable = true; + }; programs = { + hledger.enable = true; + + starship.enable = true; + rofi.enable = true; + nixos-option.enable = true; + swayidle.enable = true; + swaybg.enable = true; + foot.enable = true; + ausweisapp.enable = true; + signal.enable = true; + alacritty.enable = true; + cargo.enable = true; + calibre.enable = true; + iamb.enable = true; + mergiraf.enable = true; + lutris.enable = true; + i3bar-river.enable = true; i3status-rust.enable = true; @@ -238,6 +246,27 @@ fish.enable = true; }; + gtk.enable = true; + nix.enable = true; + + age.enable = true; + boot.enable = true; + cleanup.enable = true; + documentation.enable = true; + + fonts = { + enable = true; + enableEmoji = true; + }; + + hardware = { + enable = lib.mkDefault true; + }; + home-manager.enable = true; + + polkit.enable = true; + xdg.enable = true; + version.enable = true; }; } diff --git a/pkgs/by-name/ro/rollup/Cargo.lock b/pkgs/by-name/ro/rollup/Cargo.lock index 4184cc11..e4994453 100644 --- a/pkgs/by-name/ro/rollup/Cargo.lock +++ b/pkgs/by-name/ro/rollup/Cargo.lock @@ -111,12 +111,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -163,6 +185,47 @@ dependencies = [ "anyhow", "clap", "pretty_assertions", + "serde", + "toml", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c187e0a369471c550af028cba56d4f4fa2a489ad28151ae95a4d340a2a8b782" +dependencies = [ + "serde_core", ] [[package]] @@ -173,9 +236,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +checksum = "4ae9ccbea3a7b0b09443036490c8f34a8b1b760fd345e5c0dae0aac718faea79" dependencies = [ "proc-macro2", "quote", @@ -183,6 +246,45 @@ dependencies = [ ] [[package]] +name = "toml" +version = "1.2.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5755c51863cdac711f1956baf8eb9588e060755f7d3c4c979e70ea1e1f32cd7" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173f25c883cd2176a2d8212155638c0a60d484a9d84546d270866f40f56b6e49" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.2.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009dbb7700f11c55ef83aebbe4c0e9cf1f1ac0844bd8d6f00dc38f302026e13a" + +[[package]] name = "unicode-ident" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -210,6 +312,12 @@ dependencies = [ ] [[package]] +name = "winnow" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3b93199df0ab874cdf0c6a94f0a0dc3423fe41f1cafb62b8bd7b1deb277aef" + +[[package]] name = "yansi" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/pkgs/by-name/ro/rollup/Cargo.toml b/pkgs/by-name/ro/rollup/Cargo.toml index 51fecd59..0ce87401 100644 --- a/pkgs/by-name/ro/rollup/Cargo.toml +++ b/pkgs/by-name/ro/rollup/Cargo.toml @@ -19,3 +19,5 @@ homepage = "" clap = { version = "4.6", features = ["derive"] } anyhow = "1.0.104" pretty_assertions = "1.4.1" +serde = { version = "1.0.229", features = ["derive"] } +toml = "1.2.1" diff --git a/pkgs/by-name/ro/rollup/src/config.rs b/pkgs/by-name/ro/rollup/src/config.rs new file mode 100644 index 00000000..66bd2366 --- /dev/null +++ b/pkgs/by-name/ro/rollup/src/config.rs @@ -0,0 +1,107 @@ +use std::{ + collections::HashMap, + ffi::OsStr, + fs::{self}, + path::PathBuf, +}; + +use anyhow::{Result, bail}; +use serde::{Deserialize, Serialize}; + +pub(crate) const MAIN_CONFIG_NAME: &str = "rollup.toml"; +pub(crate) const DROP_IN_NAME: &str = ".rollup.owner"; + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct MainConfig { + pub(crate) owners: Vec<Owner>, + pub(crate) drop_ins: HashMap<PathBuf, DropInConfig>, +} + +impl MainConfig { + pub(crate) fn get_owner(&self, owner: &str) -> Result<&Owner> { + if let Some(own) = self.owners.iter().find(|o| o.name == owner) { + Ok(own) + } else { + bail!("Failed to find owner with name: `{}`", owner) + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct Owner { + pub(crate) name: String, + pub(crate) applies_to: PathBuf, + pub(crate) last_applied_tag: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct DropInConfig { + pub(crate) owners: Vec<String>, +} + +pub(crate) fn load(root: &PathBuf) -> Result<MainConfig> { + let mut main: MainConfig = { + let path = root.join(MAIN_CONFIG_NAME); + let content = fs::read_to_string(path)?; + toml::from_str(&content)? + }; + + let drop_ins = collect_drop_ins(root)?; + + for (path, config) in drop_ins { + assert!(main.drop_ins.insert(path, config).is_none()); + } + + Ok(main) +} + +fn collect_drop_ins(path: &PathBuf) -> Result<Vec<(PathBuf, DropInConfig)>> { + let mut output = vec![]; + for entry in fs::read_dir(path)? { + let entry = entry?; + let ft = entry.file_type()?; + + if ft.is_dir() { + output.extend(collect_drop_ins(&entry.path())?); + } else if ft.is_file() && entry.file_name() == OsStr::new(DROP_IN_NAME) { + let drop_in: toml::Value = { + let content = fs::read_to_string(entry.path())?; + toml::from_str(&content)? + }; + + let drop_in_config = DropInConfig { + owners: { + let Some(owner) = drop_in.get("owner") else { + bail!("Drop in config without `owner` field") + }; + if owner.is_str() { + vec![owner.as_str().expect("We checked").to_owned()] + } else if owner.is_array() { + let mut output = vec![]; + for v in owner.as_array().expect("We checked") { + if let Some(v) = v.as_str() { + output.push(v.to_owned()) + } else { + bail!("Owner value in arry not string: {}", v); + } + } + output + } else { + bail!("Owner value in drop in config not string or array") + } + }, + }; + + output.push(( + entry + .path() + .parent() + .expect("All drop-ins have a parent") + .to_owned(), + drop_in_config, + )); + } + } + + Ok(output) +} diff --git a/pkgs/by-name/ro/rollup/src/main.rs b/pkgs/by-name/ro/rollup/src/main.rs index ed4e29b4..28ef0fea 100644 --- a/pkgs/by-name/ro/rollup/src/main.rs +++ b/pkgs/by-name/ro/rollup/src/main.rs @@ -1,5 +1,7 @@ use std::{ + collections::HashMap, env::current_dir, + ffi::OsStr, fs, io::Write, path::{Path, PathBuf}, @@ -9,12 +11,20 @@ use std::{ use anyhow::{Context, Result, bail}; use clap::{Parser, Subcommand}; -use crate::parse::{FileDiff, Patch}; +use crate::{ + config::{DROP_IN_NAME, DropInConfig, MAIN_CONFIG_NAME, MainConfig, Owner}, + parse::{FileDiff, Patch}, +}; +mod config; mod parse; #[derive(Parser)] struct Cli { + /// Don't actually do anything, just check' + #[arg(long, global = true)] + dry_run: bool, + #[command(subcommand)] subcommand: Cmd, } @@ -27,10 +37,11 @@ enum Cmd { patch_files: Vec<PathBuf>, /// Which repository to use as a target for the rollup + /// It is specified via the owner, declared in the rollup.toml config. /// /// The repository needs to be clean. #[arg(short, long)] - to: PathBuf, + to: String, /// Show debug information related to the parsing of patch files. #[arg(short, long)] @@ -39,22 +50,23 @@ enum Cmd { /// Create the patch files (based on the given tag) Create { - /// Which tag to use to mark the already applied patches. - #[arg(default_value = "CONFIG_APPLIED")] - tag: String, + /// Which repository to use for the tag to base created tags on. + /// It is specified via the owner, declared in the rollup.toml config. + /// + /// The repository needs to be clean. + #[arg(short, long)] + to: String, }, /// First create the patches, and then automatically apply them. CreateApply { - /// Which tag to use to mark the already applied patches. - #[arg(default_value = "CONFIG_APPLIED")] - tag: String, - - /// Which repository to use as a target for the rollup + /// Which repository to use as a target for the rollup and the tag for new + /// patches. + /// It is specified via the owner, declared in the rollup.toml config. /// /// The repository needs to be clean. #[arg(short, long)] - to: PathBuf, + to: String, /// Show debug information related to the parsing of patch files. #[arg(short, long)] @@ -118,8 +130,24 @@ macro_rules! git { }}; } +macro_rules! drop_msg { + ($fmt:literal, $($args:expr),*) => { + eprintln!(" > {}", format!($fmt, $($args),*)); + }; +} + fn main() -> Result<()> { let args = Cli::parse(); + let root = { + let (stdout, _) = git!(in current_dir()?; "rev-parse", "--show-toplevel"); + PathBuf::from(stdout.trim()) + }; + let config = config::load(&root).with_context(|| { + format!( + "Failed to load the config (`{MAIN_CONFIG_NAME}`), in root: `{}`", + root.display() + ) + })?; match args.subcommand { Cmd::Apply { @@ -127,46 +155,69 @@ fn main() -> Result<()> { to, debug_parse, } => { - check_to(&to)?; - apply_patches(patch_files, to, debug_parse)? + let owner = config.get_owner(&to)?; + check_owner(owner)?; + apply_patches(patch_files, owner, debug_parse, &config, root, args.dry_run)? } - Cmd::Create { tag } => { - create_patches(tag)?; + Cmd::Create { to } => { + let owner = config.get_owner(&to)?; + create_patches(&owner.last_applied_tag, args.dry_run)?; } - Cmd::CreateApply { - tag, - to, - debug_parse, - } => { - check_to(&to)?; + Cmd::CreateApply { to, debug_parse } => { + let owner = config.get_owner(&to)?; + check_owner(owner)?; - let Some(patches_directory) = create_patches(tag)? else { + let Some(patches_directory) = create_patches(&owner.last_applied_tag, args.dry_run)? + else { return Ok(()); }; + let patch_files = { + let iter = fs::read_dir(&patches_directory)?; + let mut output = vec![None; iter.count()]; + let iter = fs::read_dir(patches_directory)?; - let mut output = vec![]; for entry in iter { let entry = entry?; if !entry.file_type()?.is_file() { unreachable!("Should not be able to get non-files in patches directory"); } - output.push(entry.path()); + let path = entry.path(); + let idx: usize = { + let mut file_name = path + .file_name() + .expect("Should all have a filename") + .to_str() + .expect("Should be valid utf8") + .chars(); + let number = file_name.clone().take(4).collect::<String>(); + assert_eq!(file_name.nth(4), Some('-')); + + number.parse().expect("Should parse as usize number") + }; + output[idx - 1] = Some(path); } output.sort(); output }; - apply_patches(patch_files, to, debug_parse)?; + apply_patches( + patch_files.into_iter().map(|s| s.unwrap()).collect(), + owner, + debug_parse, + &config, + root, + args.dry_run, + )?; } } Ok(()) } -fn create_patches(tag: String) -> Result<Option<PathBuf>> { +fn create_patches(tag: &str, dry_run: bool) -> Result<Option<PathBuf>> { let current_dir = current_dir()?; - let (stdout, _) = git!(in current_dir; "tag", "--contains", "HEAD", tag.as_str()); + let (stdout, _) = git!(in current_dir; "tag", "--contains", "HEAD", tag); if !stdout.is_empty() { println!( "There are no tags to generate. Tag {} already points to HEAD.", @@ -186,15 +237,29 @@ fn create_patches(tag: String) -> Result<Option<PathBuf>> { let tempdir = PathBuf::from(String::from_utf8(mktemp.stdout).unwrap().trim()); git!(in current_dir; "format-patch", format!("{}..", tag).as_str(), "-o", tempdir.display().to_string().as_str()); - git!(in current_dir; "tag", "--delete", tag.as_str()); - git!(in current_dir; "tag", "--annotate", tag.as_str(), "-m", ""); + + if dry_run { + eprintln!("Dry-run is on; Not actually moving patch tag `{tag}` forward.") + } else { + git!(in current_dir; "tag", "--delete", tag); + git!(in current_dir; "tag", "--annotate", tag, "-m", ""); + } println!("Patches have been generated here: `{}`", tempdir.display()); Ok(Some(tempdir)) } -fn apply_patches(patch_files: Vec<PathBuf>, to: PathBuf, debug_parse: bool) -> Result<()> { +fn apply_patches( + patch_files: Vec<PathBuf>, + owner: &Owner, + debug_parse: bool, + config: &MainConfig, + root: PathBuf, + dry_run: bool, +) -> Result<()> { + let applies_to = &owner.applies_to; + let mut patches = vec![]; for file in &patch_files { patches.push(parse::parse_file(file, debug_parse)?); @@ -203,11 +268,11 @@ fn apply_patches(patch_files: Vec<PathBuf>, to: PathBuf, debug_parse: bool) -> R eprintln!("Successfully parsed all {} patch files.", patches.len()); { - let (stdout, _) = git!(in to; "status", "--porcelain"); + let (stdout, _) = git!(in applies_to; "status", "--porcelain"); if !stdout.is_empty() { bail!( "`--to` (`{}`) workspace is dirty, refusing to continue.", - to.display() + applies_to.display() ); } } @@ -216,56 +281,64 @@ fn apply_patches(patch_files: Vec<PathBuf>, to: PathBuf, debug_parse: bool) -> R eprintln!( "Applying {}. patch: `{}`... ", idx + 1, - patch_files[idx].display() + patch_files[idx] + .file_name() + .expect("Has a file name") + .display() ); let mut final_diffs = vec![]; for file_diff in &patch.files { match file_diff { FileDiff::Add { path, .. } => { - if to.join(path).exists() { + if applies_to.join(path).exists() { bail!("A file was added, that already existed. This should be impossible.") } - final_diffs.push(file_diff.to_owned()); - // eprintln!(" > Keeping add of `{}`", path.display()); + if drop_in_applies(&config.drop_ins, owner, &root, path)? { + final_diffs.push(file_diff.to_owned()); + } } FileDiff::Remove { path, .. } => { - if to.join(path).exists() { - final_diffs.push(file_diff.to_owned()); - // eprintln!(" > Keeping remove of `{}`", path.display()); + if applies_to.join(path).exists() { + if drop_in_applies(&config.drop_ins, owner, &root, path)? { + final_diffs.push(file_diff.to_owned()); + } } else { - eprintln!( - " > Dropping remove of `{}`, as the file does not exist in the rollup target.", + drop_msg!( + "Dropping remove of `{}`, as the file does not exist in the rollup target.", path.display() ); } } FileDiff::RenameNoChange { from, to, .. } | FileDiff::RenameWithChange { from, to, .. } => { - if to.join(from).exists() { - if to.join(to).exists() { + if applies_to.join(from).exists() { + if applies_to.join(to).exists() { bail!( "A rename (`{}` -> `{}`) tried to rename a path to an already existing path. This should be impossible.", from.display(), to.display() ) } - final_diffs.push(file_diff.to_owned()); - // eprintln!(" > Keeping rename of `{}` to `{}`", from.display(), to.display()); + if drop_in_applies(&config.drop_ins, owner, &root, to)? { + final_diffs.push(file_diff.to_owned()); + } } else { - eprintln!( - " > Dropping rename from `{}` to `{}`, as the from file does not exist in the rollup target.", + drop_msg!( + "Dropping rename from `{}` to `{}`, as the from file does not exist in the rollup target.", from.display(), to.display() ); } } FileDiff::Change { path, .. } => { - if to.join(path).exists() { - final_diffs.push(file_diff.to_owned()); + if applies_to.join(path).exists() { + if drop_in_applies(&config.drop_ins, owner, &root, path)? { + final_diffs.push(file_diff.to_owned()); + } } else { - eprintln!( - " > Dropping change to `{}`, as the file does not exist in the rollup target.", + drop_msg!( + "Dropping change to `{}`, as the file does not exist in the rollup target.", path.display() ); } @@ -283,15 +356,20 @@ fn apply_patches(patch_files: Vec<PathBuf>, to: PathBuf, debug_parse: bool) -> R ..patch.to_owned() }; - git!(@set_stdin_to filtered_patch; in to; "apply", "-", "--whitespace=nowarn"); - git!(in to; "add", "."); - git!(@set_stdin_to filtered_patch.commit_message; in to; "commit", "--file=-", format!("--date={}", filtered_patch.date).as_str(), "--quiet"); + if dry_run { + eprintln!(" (Dry-run is on; Not applying.)"); + } else { + git!(@set_stdin_to filtered_patch; in applies_to; "apply", "-", "--whitespace=nowarn"); + git!(in applies_to; "add", "."); + git!(@set_stdin_to filtered_patch.commit_message; in applies_to; "commit", "--file=-", format!("--date={}", filtered_patch.date).as_str(), "--quiet"); + } } Ok(()) } -fn check_to(to: &Path) -> Result<()> { +fn check_owner(owner: &Owner) -> Result<()> { + let to = &owner.applies_to; let to = to.join(".git"); // NOTE: We cannot just try to stat() the path, because landlock might be in use and does not @@ -313,3 +391,69 @@ fn check_to(to: &Path) -> Result<()> { Ok(()) } + +fn drop_in_applies( + drop_ins: &HashMap<PathBuf, DropInConfig>, + owner: &Owner, + root: &Path, + original_path: &Path, +) -> Result<bool> { + let path = &original_path.canonicalize()?; + + let file_name = path.file_name().expect("All paths are to files"); + if file_name == OsStr::new(DROP_IN_NAME) || file_name == OsStr::new(MAIN_CONFIG_NAME) { + drop_msg!( + "Not applying change to `{}`, because it's a rollup config or drop in.", + path.display() + ); + + return Ok(false); + } + + if path.parent() == Some(root) { + return Ok(true); + } + + let path = PathBuf::from( + &path + .display() + .to_string() + .strip_prefix(format!("{}/", root.display()).as_str()) + .expect("All paths are in root"), + ); + + if let Some(conf) = drop_ins.get(&path) + && conf.owners.contains(&owner.name) + { + return Ok(true); + } + + let mut parent: &Path = &path; + while let Some(next) = parent.parent() { + // eprintln!("Checking `{}` for drop-ins..", next.display()); + + if let Some(conf) = drop_ins.get(&root.join(next)) { + // eprint!("Found a drop-in for `{}`", next.display()); + if !conf.owners.contains(&owner.name) { + // eprintln!(", but it's for `{}`, so ignoring path.", conf.owner); + drop_msg!( + "Dropping `{}` as `{}` says this dir is for `{}` (but we look for `{}`).", + original_path.display(), + next.join(DROP_IN_NAME).display(), + conf.owners.join(", "), + owner.name + ); + return Ok(false); + } else { + // eprintln!(", which matches."); + return Ok(true); + } + } + parent = next; + } + + bail!( + "There was no drop-in config defining path ownership for: `{}`", + path.display() + ); +} |
