diff options
Diffstat (limited to 'modules/by-name/gi')
-rw-r--r-- | modules/by-name/gi/git-server/css.nix | 116 | ||||
-rw-r--r-- | modules/by-name/gi/git-server/module.nix | 178 |
2 files changed, 294 insertions, 0 deletions
diff --git a/modules/by-name/gi/git-server/css.nix b/modules/by-name/gi/git-server/css.nix new file mode 100644 index 0000000..3d73ea0 --- /dev/null +++ b/modules/by-name/gi/git-server/css.nix @@ -0,0 +1,116 @@ +{cgitPkg, pkgs}: let + /* + Adapted from `https://git.qyliss.net/nixlib/sys/atuin.nix`, originally distributed under + the MIT license. + */ + cgitCss = + pkgs.runCommand "cgit-extra.css" { + licenseHeader = '' + /* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * See <https://www.gnu.org/licenses/>. + */ + + ''; + + # Adapted from + # <https://git.causal.agency/src/plain/www/git.causal.agency/custom.css>, + # distributed as a Larger Work under a Secondary License, + # as permitted by the terms of the + # Mozilla Public License Version 2.0. + extraCss = '' + * { line-height: 1.25em; } + + article { + font-family: sans-serif; + max-width: 70ch; + margin-left: auto; + margin-right: auto; + } + + div#cgit { + margin: auto; + font-family: monospace; + -moz-tab-size: 4; + tab-size: 4; + display: table; + } + + div#cgit table#header { + margin-left: auto; + margin-right: auto; + } + div#cgit table#header td.logo { + display: none; + } + div#cgit table#header td.main { + font-size: 1em; + font-weight: bold; + } + div#cgit table#header td.sub { + border-top: none; + } + div#cgit table.tabs { + margin-left: auto; + margin-right: auto; + border-bottom: none; + } + div#cgit div.content { + border-bottom: none; + min-width: 108ch; + } + div#cgit div.content div#summary { + display: table; + margin-left: auto; + margin-right: auto; + } + div#cgit div.notes { + border: none; + background: transparent; + padding: 0; + } + div#cgit table.list { + margin-left: auto; + margin-right: auto; + } + div#cgit table.list th a { + color: inherit; + } + div#cgit table.list tr:nth-child(even) { + background: inherit; + } + div#cgit table.list tr:hover { + background: inherit; + } + div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { + background: inherit; + } + div#cgit div.footer { + font-size: 1em; + margin-top: 0; + } + + div#cgit table.blob td.linenumbers:nth-last-child(3) { + display: none; + } + + div#cgit table.blob td.linenumbers a:target { + color: goldenrod; + text-decoration: underline; + outline: none; + } + ''; + passAsFile = ["licenseHeader" "extraCss"]; + } '' + cat $licenseHeaderPath ${cgitPkg}/cgit/cgit.css $extraCssPath > $out + ''; +in + cgitCss diff --git a/modules/by-name/gi/git-server/module.nix b/modules/by-name/gi/git-server/module.nix new file mode 100644 index 0000000..a374f4c --- /dev/null +++ b/modules/by-name/gi/git-server/module.nix @@ -0,0 +1,178 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.vhack.git-server; + + cgitCss = import ./css.nix { + inherit pkgs; + cgitPkg = + config.services.cgit."${cfg.domain}".package; + }; +in { + options.vhack.git-server = { + enable = lib.mkEnableOption '' + a lightweight git-server, realised with cgit and gitolite. + ''; + + domain = lib.mkOption { + type = lib.types.str; + default = "git.vhack.eu"; + description = '' + The domain this git instance will run under. + ''; + }; + + gitolite = { + adminPubkey = lib.mkOption { + description = '' + The initial key to use for gitolite. This will only be used for the initial + clone of the `gitolite-admin` repository. + ''; + type = lib.types.str; + default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAe4o1PM6VasT3KZNl5NYvgkkBrPOg36dqsywd10FztS openpgp:0x21D20D6A"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + programs.git = { + enable = true; + config = { + init = { + defaultBranch = "main"; + }; + }; + }; + + # Needed for the nginx proxy and the virtual host + vhack.nginx.enable = true; + + services = { + gitolite = { + inherit (cfg.gitolite) adminPubkey; + enable = true; + dataDir = "/srv/gitolite"; + user = "git"; + group = "git"; + extraGitoliteRc = '' + $RC{UMASK} = 0027; # Enable group access, important for cgit. + + # Enable modifing git variables (for cgit.owner and such things) + # These must be enable in the gitolite-admin repo (option user-configs = ...) + push( @{$RC{ENABLE}}, 'config' ); + push( @{$RC{ENABLE}}, 'git-config' ); + + push( @{$RC{ENABLE}}, 'expand-deny-messages' ); + push( @{$RC{ENABLE}}, 'Motd' ); + + push( @{$RC{ENABLE}}, 'cgit' ); + ''; + }; + + cgit."${cfg.domain}" = { + enable = true; + package = pkgs.cgit-pink; + scanPath = "${config.services.gitolite.dataDir}/repositories"; + user = "git"; + group = "git"; + settings = { + branch-sort = "age"; + + # Allow users to download a repo checkout with these compression formats + snapshots = ["tar.gz" "zip"]; + # The template used to generate the clone url for https clone. + clone-url = [ + "https://${cfg.domain}/$CGIT_REPO_URL" + "ssh://git@${cfg.domain}/$CGIT_REPO_URL" + ]; + enable-http-clone = true; + + # TODO: We might want to add an logo and readme here <2024-07-31> + # logo = "<url>"; + # root-readme = "/some/readme/file" + root-desc = "The cgit instance of ${cfg.domain}!"; + root-title = "${ + lib.strings.toUpper (builtins.substring 0 1 cfg.domain) + builtins.substring 1 (builtins.stringLength cfg.domain) cfg.domain + } cgit instace"; + + # Set the default maximum statistics period. Valid values are "week", + # "month", "quarter" and "year". + max-stats = "week"; + + readme = [ + ":README.md" + ":readme.md" + ":README.mkd" + ":readme.mkd" + ":README.rst" + ":readme.rst" + ":README.html" + ":readme.html" + ":README.htm" + ":readme.htm" + ":README.txt" + ":readme.txt" + ":README" + ":readme" + ":INSTALL.md" + ":install.md" + ":INSTALL.mkd" + ":install.mkd" + ":INSTALL.rst" + ":install.rst" + ":INSTALL.html" + ":install.html" + ":INSTALL.htm" + ":install.htm" + ":INSTALL.txt" + ":install.txt" + ":INSTALL" + ":install" + ]; + + enable-blame = true; + enable-commit-graph = true; + enable-subject-links = true; + enable-follow-links = true; + enable-index-links = true; + enable-index-owner = true; + + # NOTE: This allows cgit to take configuration from the bare git repositories: + # All `repo.<key>` can be set by setting `cgit.<key>` in the git config. E.g.: + # setting the owner (i.e. `repo.owner`) would be done by setting the + # `cgit.owner` config. All repo options are outline in the cgitrc (5) man page. + enable-git-config = true; + + # Remove the `.git` suffix from scanned repositories (this must be set _before_ `scan-path`) + remove-suffix = true; + + css = "/custom_cgit.css"; + + # This is a number of path elements to treat as section. + # `-1` means that we treat the last element as name, all others as sections + section-from-path = -1; + + project-list = "${config.services.gitolite.dataDir}/projects.list"; + + # TODO: We might want to use the kernel.org `libravatar.lua` email-filter <2024-07-31> + source-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/syntax-highlighting.py"; + about-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/about-formatting.sh"; + }; + }; + + nginx.virtualHosts."${cfg.domain}" = { + enableACME = true; + forceSSL = true; + + locations = { + "= /custom_cgit.css" = { + alias = cgitCss.outPath; + }; + }; + }; + }; + }; +} |