feat: Hud-db packageset

This commit is contained in:
Madeleine Sydney
2025-04-11 07:30:01 -06:00
parent fcbbf6be72
commit 948f6a653e
11 changed files with 2493 additions and 18 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
tf2/packages/huds/hud-db/hud-db.json linguist-generated=true

View File

@@ -98,14 +98,20 @@ TODO!
TODO! TODO!
*** HUDs
A package set of HUDs is generated primarily using data from [[https://github.com/mastercomfig/hud-db][hud-db]], with a handful of manual additions and overrides. These HUDs are provided
* Contributing * Contributing
Don't hesitate to open issues/PRs not only for "real issues" (bugs, missing features) but for poor UX, bad code, or anything else. Don't hesitate to open issues/PRs not only for "real issues" (bugs, missing features) but for poor UX, bad code, or anything else.
* To-do list * To-do list
- [ ] Generate a package set from [[https://github.com/mastercomfig/hud-db][hud-db]]. - [X] Generate a package set from [[https://github.com/mastercomfig/hud-db][hud-db]].
- [ ] Mastercomfig comfig.app wrapper. - [ ] Support non-GitHub HUDs from [[https://github.com/mastercomfig/hud-db][hud-db]].
- [ ] CI action to update hud-db.
- [ ] Mastercomfig [[https://comfig.app/][comfig.app]] wrapper.
- [ ] VPK builder. - [ ] VPK builder.
- [ ] Configure launch options (Is this feasible?). - [ ] Configure launch options (Is this feasible?).
- [ ] A higher-level NixOS/Home-manager module. - [ ] A higher-level NixOS/Home-manager module.

34
flake.lock generated
View File

@@ -1,5 +1,23 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1743568003, "lastModified": 1743568003,
@@ -18,8 +36,24 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
} }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View File

@@ -3,16 +3,17 @@
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, ... }@inputs: outputs = { self, ... }@inputs:
inputs.flake-utils.lib.eachDefaultSystem (system:
let let
system = "x86_64-linux";
pkgs = import inputs.nixpkgs { inherit system; }; pkgs = import inputs.nixpkgs { inherit system; };
lib = pkgs.lib; lib = pkgs.lib;
in { in {
packages.x86_64-linux = import ./tf2/packages { packages = import ./tf2/packages {
inherit pkgs lib; inherit pkgs lib;
}; };
}; });
} }

View File

@@ -31,12 +31,14 @@ let
}; };
extra-args = { extra-args = {
inherit mkTf2Config fetchFromGameBanana mkCfg mergeTf2Configs; inherit mkTf2Config fetchFromGameBanana mkCfg mergeTf2Configs callPackage;
}; };
callPackage = lib.callPackageWith (pkgs // extra-args);
in lib.mergeAttrsList [ in lib.mergeAttrsList [
extra-args { inherit mkTf2Config fetchFromGameBanana mkCfg mergeTf2Configs; }
{ mastercomfig = pkgs.callPackage ./mastercomfig.nix extra-args; } { mastercomfig = callPackage ./mastercomfig.nix {}; }
(pkgs.callPackage ./huds.nix extra-args) { huds = callPackage ./huds {}; }
(pkgs.callPackage ./misc.nix extra-args) (callPackage ./misc.nix {})
(pkgs.callPackage ./scripts.nix extra-args) (callPackage ./scripts.nix {})
] ]

View File

@@ -0,0 +1,10 @@
{ pkgs, callPackage, fetchFromGitHub, mkTf2Config }@args:
let
hud-db = callPackage ./hud-db {
inherit fetchFromGitHub mkTf2Config;
};
extras = callPackage ./extras.nix {
inherit fetchFromGitHub mkTf2Config;
};
in hud-db // extras

View File

@@ -1,4 +1,4 @@
{ fetchFromGitHub, mkTf2Config, ... }: { fetchFromGitHub, mkTf2Config }:
{ {
deerhud = mkTf2Config { deerhud = mkTf2Config {

View File

@@ -0,0 +1,13 @@
{ mkTf2Config, fetchFromGitHub }:
builtins.mapAttrs
(name: e: mkTf2Config {
pname = name;
env.description = e.description;
custom = [
(fetchFromGitHub (builtins.removeAttrs e.src ["__type"] // {
inherit name;
}))
];
})
(builtins.fromJSON (builtins.readFile ./hud-db.json))

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p babashka
bb -cp . -m fetch-hud-db > hud-db.json

View File

@@ -0,0 +1,112 @@
(ns fetch-hud-db
(:require [babashka.fs :as fs]
[babashka.process :as p]
[cheshire.core :as json]
[clojure.tools.logging :as l]
[clojure.string :as str]))
(def hud-db-root (or (System/getenv "HUD_DB_ROOT")
(fs/expand-home "~/git/hud-db")))
(def ^:dynamic *dry-run?* true)
(defmacro race [x y]
`(let [p# (promise)
f1# (future (deliver p# ~x))
f2# (future (deliver p# ~y))
winner# @p#]
(future-cancel f1#)
(future-cancel f2#)
winner#))
;; Hud-db only tracks GitHub repos.
(defn prefetch
"Prefetch a Git repo and return the Nix SRI hash."
[url rev]
(let [command ["nix-prefetch-git"
"--quiet"
"--url" url
"--rev" rev]]
(if *dry-run?*
(do (apply println "$" command)
"«hash»")
(when-some [data (race (apply p/shell {:out :string} command)
(do (Thread/sleep (* 60 1000))
(binding [*out* *err*]
(l/warnf "Timed out whilst fetching %s" url))
nil))]
(-> data :out (json/decode keyword) :hash)))))
(defn parse-github-url [url]
(when-some [[_ owner repo]
;; Not the most correct way to do this.
(re-find #"github\.com/([^/]+)/([^/]+)$" url)]
{:owner owner :repo repo}))
(def cache-dir (fs/xdg-cache-home "fetch-hud-db"))
(def huds-cache-dir (fs/file cache-dir "huds"))
(defn prefetch*
"A caching variant of `prefetch`."
[owner repo url rev]
(let [name (str owner "###" repo)
cache-entry (fs/file huds-cache-dir name rev)]
(if (fs/exists? cache-entry)
(let [cached-result (slurp cache-entry)]
(if (empty? cached-result)
nil
cached-result))
(let [hash (prefetch url rev)]
(when (and hash
;; During dry runs, `prefetch` will return fake hashes that
;; we don't want to pollute the cache with.
(not *dry-run?*))
(fs/create-dirs (fs/parent cache-entry))
(spit cache-entry hash))
hash))))
(defn fetch-hud
"Construct a map with the necessary info to package a HUD from Hud-db. `name`
is expected to be the package's name, while `data` is a map parsed from
Hud-db's JSON data files. At the moment, only huds associated with GitHub
repos are supported. Returns nil on failure."
[name data]
(binding [*out* *err*]
(l/infof "Fetching %s" name))
(let [url (:repo data)]
(when-some [{:keys [owner repo]} (parse-github-url url)]
(let [;; N.B. hud-db uses 'hash' to refer to the Git revision hash, while
;; we use it to mean the Nix SRI hash.
rev (:hash data)]
(when-some [hash (prefetch* owner repo url rev)]
{:description (format "%s for TF2, by %s" (:name data) (:author data))
;; For forward-compatibility, when we hopefully add support those
;; pesky non-GitHub downloads.
:src {:__type "github"
:owner owner
:repo repo
:rev rev
:hash hash}})))))
(defn fetch-hud-db
"Fetch each HUD from the data files `hud-db-root`/hud-data/*.json and return
a map of each HUD."
[]
(into {}
(for [hud-data-path (fs/glob (fs/path hud-db-root "hud-data") "*.json")]
(let [hud-name (-> hud-data-path fs/file-name fs/strip-ext)
hud-data (-> hud-data-path fs/file slurp (json/decode keyword))]
;; See the docstring on `broken-huds`.
(if-some [hud (fetch-hud hud-name hud-data)]
[(keyword hud-name)
hud]
(binding [*out* *err*]
(l/warnf "Skipping HUD `%s`" hud-name )
nil))))))
(defn -main []
(binding [*dry-run?* false]
(-> (fetch-hud-db)
json/encode
print)))

2292
tf2/packages/huds/hud-db/hud-db.json generated Normal file

File diff suppressed because it is too large Load Diff