https://dev.kronoz.win/r/rgit.git
1{
2 inputs = {
3 nixpkgs.url = "github:NixOS/nixpkgs/staging-next";
4
5 crane.url = "github:ipetkov/crane";
6 utils.url = "github:numtide/flake-utils";
7 treefmt-nix.url = "github:numtide/treefmt-nix";
8
9 advisory-db = {
10 url = "github:rustsec/advisory-db";
11 flake = false;
12 };
13
14 helix = {
15 url = "github:JordanForks/helix";
16 flake = false;
17 };
18 };
19
20 outputs = { self, nixpkgs, utils, crane, advisory-db, treefmt-nix, helix }:
21 utils.lib.eachDefaultSystem (system:
22 let
23 pkgs = import nixpkgs { inherit system; };
24 craneLib = crane.mkLib pkgs;
25 src = craneLib.cleanCargoSource ./.;
26 helix-grammar = pkgs.callPackage "${helix}/grammars.nix" { inherit pkgs; };
27 rgit-grammar = pkgs.runCommand "consolidated-rgit-grammars" { } ''
28 mkdir -p $out
29 for file in ${helix-grammar}/*; do
30 ln -s "$file" "$out/libtree-sitter-$(basename "$file")"
31 done
32 ln -s "${helix}/languages.toml" "$out/languages.toml"
33 ln -s "${helix}/runtime/queries" "$out/queries"
34 '';
35 commonArgs = {
36 inherit src;
37 strictDeps = true;
38 buildInputs = pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ];
39 nativeBuildInputs = with pkgs; [ cmake clang ];
40 LIBCLANG_PATH = "${pkgs.clang.cc.lib}/lib";
41 ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib";
42 TREE_SITTER_GRAMMAR_LIB_DIR = "${rgit-grammar}";
43 };
44 cargoArtifacts = craneLib.buildDepsOnly commonArgs;
45 rgit = craneLib.buildPackage (commonArgs // {
46 inherit cargoArtifacts;
47 doCheck = false;
48 src = pkgs.lib.fileset.toSource {
49 root = ./.;
50 fileset = pkgs.lib.fileset.unions [
51 ./Cargo.toml
52 ./Cargo.lock
53 ./tree-sitter-grammar-repository
54 ./src
55 ./statics
56 ./templates
57 ./themes
58 ./build.rs
59 ];
60 };
61 });
62 treefmt = treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
63 in
64 {
65 checks = {
66 inherit rgit;
67 rgit-clippy = craneLib.cargoClippy (commonArgs // {
68 inherit cargoArtifacts;
69 cargoClippyExtraArgs = "--all --all-targets --all-features";
70 });
71 rgit-doc = craneLib.cargoDoc (commonArgs // { inherit cargoArtifacts; });
72 rgit-audit = craneLib.cargoAudit { inherit src advisory-db; };
73 rgit-test = craneLib.cargoNextest (commonArgs // {
74 inherit cargoArtifacts;
75 partitions = 1;
76 partitionType = "count";
77 });
78 formatting = treefmt.config.build.check self;
79 };
80
81 formatter = treefmt.config.build.wrapper;
82
83 packages.default = rgit;
84 apps.default = utils.lib.mkApp { drv = rgit; };
85
86 devShells.default = craneLib.devShell {
87 checks = self.checks.${system};
88 };
89
90 nixosModules.default = { config, lib, pkgs, ... }:
91 with lib;
92 let
93 cfg = config.services.rgit;
94 in
95 {
96 options.services.rgit = {
97 enable = mkEnableOption "rgit";
98 bindAddress = mkOption {
99 default = "[::]:8333";
100 description = "Address and port to listen on";
101 type = types.str;
102 };
103 dbStorePath = mkOption {
104 default = "/tmp/rgit.db";
105 description = "Path to store the temporary cache";
106 type = types.path;
107 };
108 repositoryStorePath = mkOption {
109 default = "/git";
110 description = "Path to repositories";
111 type = types.path;
112 };
113 requestTimeout = mkOption {
114 default = "10s";
115 description = "Timeout for incoming HTTP requests";
116 type = types.str;
117 };
118 package = mkOption {
119 default = rgit;
120 description = "rgit package to use";
121 type = types.package;
122 };
123 };
124
125 config = mkIf cfg.enable {
126 users.groups.rgit = { };
127 users.users.rgit = {
128 description = "RGit service user";
129 group = "rgit";
130 isSystemUser = true;
131 home = "/git";
132 };
133
134 systemd.services.rgit = {
135 enable = true;
136 wantedBy = [ "multi-user.target" ];
137 after = [ "network-online.target" ];
138 path = [ pkgs.git ];
139 serviceConfig = {
140 Type = "exec";
141 ExecStart = "${cfg.package}/bin/rgit --request-timeout ${cfg.requestTimeout} --db-store ${cfg.dbStorePath} ${cfg.bindAddress} ${cfg.repositoryStorePath}";
142 Restart = "on-failure";
143
144 User = "rgit";
145 Group = "rgit";
146
147 CapabilityBoundingSet = "";
148 NoNewPrivileges = true;
149 PrivateDevices = true;
150 PrivateTmp = true;
151 PrivateUsers = true;
152 PrivateMounts = true;
153 ProtectHome = true;
154 ProtectClock = true;
155 ProtectProc = "noaccess";
156 ProcSubset = "pid";
157 ProtectKernelLogs = true;
158 ProtectKernelModules = true;
159 ProtectKernelTunables = true;
160 ProtectControlGroups = true;
161 ProtectHostname = true;
162 RestrictSUIDSGID = true;
163 RestrictRealtime = true;
164 RestrictNamespaces = true;
165 LockPersonality = true;
166 RemoveIPC = true;
167 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
168 SystemCallFilter = [ "@system-service" "~@privileged" ];
169 };
170 };
171 };
172 };
173 });
174}