about summary refs log tree commit diff
path: root/modules/git
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2024-04-21 02:15:42 +0300
committerAzat Bahawi <azat@bahawi.net>2024-04-21 02:15:42 +0300
commite6ed60548397627bf10f561f9438201dbba0a36e (patch)
treef9a84c5957d2cc4fcd148065ee9365a0c851ae1c /modules/git
parent2024-04-18 (diff)
2024-04-21
Diffstat (limited to 'modules/git')
-rw-r--r--modules/git/default.nix300
-rw-r--r--modules/git/favicon.icobin0 -> 15406 bytes
-rw-r--r--modules/git/logo.gifbin0 -> 138553 bytes
3 files changed, 300 insertions, 0 deletions
diff --git a/modules/git/default.nix b/modules/git/default.nix
new file mode 100644
index 0000000..a65c31e
--- /dev/null
+++ b/modules/git/default.nix
@@ -0,0 +1,300 @@
+{
+  config,
+  inputs,
+  lib,
+  libNginx,
+  libPlausible,
+  pkgs,
+  ...
+}:
+with lib;
+let
+  cfg = config.nixfiles.modules.git;
+in
+{
+  options.nixfiles.modules.git = {
+    client.enable = mkEnableOption "Git client";
+
+    server = {
+      enable = mkEnableOption "Git server";
+
+      domain = mkOption {
+        description = "Domain name sans protocol scheme.";
+        type = with types; nullOr str;
+        default = "git.${config.networking.domain}";
+      };
+
+      package = mkOption {
+        description = "Package.";
+        type = types.package;
+        default = pkgs.cgit;
+      };
+    };
+  };
+
+  config = mkMerge [
+    (mkIf cfg.client.enable {
+      secrets = {
+        glab-cli-config = {
+          file = "${inputs.self}/secrets/glab-cli-config";
+          path = "${config.dirs.config}/glab-cli/config.yml";
+          owner = my.username;
+        };
+        gh-hosts = {
+          file = "${inputs.self}/secrets/gh-hosts";
+          path = "${config.dirs.config}/gh/hosts.yml";
+          owner = my.username;
+        };
+        hut = {
+          file = "${inputs.self}/secrets/hut";
+          path = "${config.dirs.config}/hut/config";
+          owner = my.username;
+        };
+      };
+
+      nixfiles.modules.common.shell.aliases = {
+        gl = "glab";
+        ht = "hut";
+      };
+
+      hm = {
+        home.packages = with pkgs; [
+          git-extras
+          glab
+          hut
+        ];
+
+        programs = {
+          git = {
+            enable = true;
+
+            package = pkgs.git.override {
+              doInstallCheck = false;
+              pythonSupport = false;
+              sendEmailSupport = true;
+              withLibsecret = false;
+              withSsh = true;
+            };
+
+            userName = my.fullname;
+            userEmail = my.email;
+            signing = {
+              inherit (my.pgp) key;
+              signByDefault = true;
+            };
+
+            extraConfig =
+              {
+                color.ui = true;
+                core.whitespace = "trailing-space";
+                init.defaultBranch = "master";
+                status.submoduleSummary = true;
+                commit.verbose = true;
+                push.autoSetupRemote = true;
+                pull.rebase = true;
+                rebase = {
+                  autoStash = true;
+                  autoSquash = true;
+                };
+                rerere.enabled = true;
+                branch.sort = "-committerdate";
+                diff = {
+                  mnemonicPrefix = true;
+                  renames = "copies";
+                  submodule = "log";
+                };
+                submodule.recurse = true;
+                sendemail = rec {
+                  smtpServer = my.domain.shire;
+                  smtpUser = "${my.username}@${smtpServer}";
+                  smtpEncryption = "ssl";
+                  smtpServerPort = 465;
+                  annotate = true;
+                  confirm = "always";
+                };
+                column.ui = "auto";
+                github.user = my.username;
+                gitlab.user = my.username;
+              }
+              // mapAttrs' (name: value: nameValuePair ''url "git@${value}:"'' { insteadOf = "${name}:"; }) {
+                "bitbucket" = "bitbucket.com";
+                "codeberg" = "codeberg.org";
+                "github" = "github.com";
+                "gitlab" = "gitlab.com";
+                "sourcehut" = "git.sr.ht";
+              }
+              //
+                mapAttrs' (name: values: nameValuePair ''url "https://${values}/"'' { insteadOf = "${name}:"; })
+                  {
+                    "alpine" = "gitlab.alpinelinux.org";
+                    "debian" = "salsa.debian.org";
+                    "freedesktop" = "gitlab.freedesktop.org";
+                    "gnome" = "gitlab.gnome.org";
+                    "haskell" = "gitlab.haskell.org";
+                    "homotopic" = "gitlab.homotopic.tech";
+                    "horizon" = "gitlab.horizon-haskell.net";
+                    "kde" = "invent.kde.org";
+                    "nixca" = "gitlab.nixca.dev";
+                    "notabug" = "notabug.org";
+                    "opencode" = "opencode.net";
+                    "torproject" = "gitlab.torproject.org";
+                    "videolan" = "code.videolan.org";
+                  };
+
+            aliases =
+              let
+                git = getExe config.hm.programs.git.package;
+                curl = getExe pkgs.curl;
+              in
+              {
+                amend = "commit --amend";
+                cat = "cat-file -p";
+                fast = "clone --depth=1";
+                fixup = "commit --fixup";
+                fuck = "!${git} reset --hard && ${git} clean --force -dx";
+                get = "pull --all --recurse-submodules --autostash";
+                gud = ''commit -m "git gud"'';
+                refresh = "clean --force -dx";
+                tree = "log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'";
+                uncommit = "reset --soft HEAD~1";
+                untrack = "rm --cache --";
+                wtc = "!${curl} -sq whatthecommit.com/index.txt | ${git} commit -F -";
+              };
+
+            # All helper tools/editor generated files should go here. This must be
+            # kept void of any project-specific or residual files.
+            ignores = [
+              "*~"
+              ".DS_Store"
+              ".cache/clangd/"
+              ".ccls-cache/"
+              ".gdb_history"
+              ".netrwhist"
+              ".projectile"
+              "[._]*.s[a-v][a-z]"
+              "[._]*.sw[a-p]"
+              "[._]s[a-rt-v][a-z]"
+              "[._]ss[a-gi-z]"
+              "[._]sw[a-p]"
+              "\#*\#"
+              "compile_commands*.json"
+              "cscope.*"
+              "vgcore.*"
+            ];
+          };
+
+          gh = {
+            enable = true;
+            settings.git_protocol = "ssh";
+          };
+        };
+      };
+    })
+    (mkIf cfg.server.enable {
+      ark.directories = [ config.services.gitolite.dataDir ];
+
+      nixfiles.modules.nginx = {
+        enable = true;
+        virtualHosts.${cfg.server.domain} = {
+          locations = {
+            "/".extraConfig =
+              let
+                cgitrc = pkgs.writeText "cgitrc" ''
+                  root-title=github sux (⩺_⩹)
+                  root-desc=https://github.com/azahi
+
+                  clone-url=https://${cfg.server.domain}/$CGIT_REPO_URL
+
+                  logo=/cgit-custom-logo.gif
+                  favicon=/cgit-custom-favicon.gif
+                  css=/cgit-custom-style.css
+
+                  about-filter=${cfg.server.package}/lib/cgit/filters/about-formatting.sh
+                  source-filter=${cfg.server.package}/lib/cgit/filters/syntax-highlighting.py
+                  commit-filter=${cfg.server.package}/lib/cgit/filters/commit-links.sh
+
+                  enable-git-config=1
+                  enable-gitweb-owner=1
+                  remove-suffix=1
+
+                  readme=:README
+                  readme=:README.md
+                  readme=:README.org
+                  readme=:README.txt
+                  readme=:readme
+                  readme=:readme.md
+                  readme=:readme.org
+                  readme=:readme.txt
+
+                  scan-path=${config.services.gitolite.dataDir}/repositories
+                '';
+              in
+              ''
+                include ${config.services.nginx.package}/conf/fastcgi_params;
+                fastcgi_split_path_info ^(/?)(.+)$;
+                fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
+                fastcgi_param SCRIPT_FILENAME ${cfg.server.package}/cgit/cgit.cgi;
+                fastcgi_param CGIT_CONFIG ${cgitrc};
+                fastcgi_param PATH_INFO $uri;
+                fastcgi_param QUERY_STRING $args;
+                fastcgi_param HTTP_HOST $server_name;
+
+                ${libNginx.config.appendHead [
+                  ''<meta name="go-import" content="$host$uri git https://$host$uri">''
+                  (libPlausible.htmlPlausibleScript { inherit (cfg.server) domain; })
+                ]}
+              '';
+            "~* ^.+(cgit.css|robots.txt)$".extraConfig = ''
+              root ${cfg.server.package}/cgit;
+            '';
+            "~* ^.+cgit-custom-logo.gif$".extraConfig = ''
+              alias ${./logo.gif};
+            '';
+            "~* ^.+cgit-custom-favicon.gif$".extraConfig = ''
+              alias ${./favicon.ico};
+            '';
+            "~* ^.+cgit-custom-style.css$".extraConfig =
+              let
+                css = pkgs.writeText "custom.css" ''
+                  @import url("cgit.css");
+
+                  div#cgit {
+                    font-family: monospace;
+                    -moz-tab-size: 4;
+                    tab-size: 4;
+                  }
+                '';
+              in
+              ''
+                alias ${css};
+              '';
+          };
+        };
+      };
+
+      services =
+        let
+          user = "git";
+          group = "git";
+        in
+        {
+          gitolite = {
+            enable = true;
+            inherit user group;
+            adminPubkey = my.ssh.key;
+            extraGitoliteRc = ''
+              # This allows hiding repositories via "cgit.ignore"[1].
+              #
+              # [1]: https://www.omarpolo.com/post/cgit-gitolite.html
+              $RC{GIT_CONFIG_KEYS} = '.*';
+            '';
+          };
+
+          fcgiwrap = {
+            enable = true;
+            inherit user group;
+          };
+        };
+    })
+  ];
+}
diff --git a/modules/git/favicon.ico b/modules/git/favicon.ico
new file mode 100644
index 0000000..bb7cc39
--- /dev/null
+++ b/modules/git/favicon.ico
Binary files differdiff --git a/modules/git/logo.gif b/modules/git/logo.gif
new file mode 100644
index 0000000..05874f9
--- /dev/null
+++ b/modules/git/logo.gif
Binary files differ

Consider giving Nix/NixOS a try! <3