# sorcery tiny read-only git repo viewer - point at a dir containing `user/repo` bare git repos - generates static sites for every repo - serves via nginx (or other proxy supporting the `X-Accel` headers) - progressively enhances via js to provide dynamic content (commit diffs, tree-at-revision, etc) - syntax highlighting via arborium (both serverside and clientside) - supports "git smart HTTP" for read-only clones pairs well with ssh git for read-write access ## usage compiles to a static executable (linux musl) on the default package in the flake: ```sh nix build ``` install it as `/usr/local/bin/sorceryd` or whatever ## nginx production nginx config generated via [`@char/ngx`](https://jsr.io/@char/ngx): ```sh deno run sorcery.ngx.ts > sorcery.conf ``` ## systemd Example `/etc/systemd/system/sorceryd.service`: ```ini [Unit] Description=Sorcery Git forge After=network.target [Service] Type=simple User=git Group=git RuntimeDirectory=sorcery CacheDirectory=sorcery ConfigurationDirectory=sorcery EnvironmentFile=/etc/sorcery/env ExecStart=/usr/local/bin/sorceryd Restart=on-failure RestartSec=2 UMask=0027 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=read-only [Install] WantedBy=multi-user.target ``` With `/etc/sorcery/env`: ```sh SORCERY_REPOSITORIES=/home/git/public SORCERY_CACHE=/var/cache/sorcery SORCERY_SOCKET=/run/sorcery/sock SORCERY_INSTANCE_NAME=my-cool-git.example SORCERY_CLONE_URL_BASE=https://my-cool-git.example SORCERY_REFRESH_TOKEN_FILE=/etc/sorcery/refresh-token ``` Command-line flags remain available and override the corresponding environment variables. ## ssh `sorcery-ssh` is an sshd `ForceCommand` that provides read-write git access. it auto-creates bare repositories on first push (like sourcehut) and also provides commands + an optional interactive tui for editing the description of a repo. ```sh nix build .#sorcery-ssh nix build .#sorcery-ssh-tui # optional ``` install `sorcery-ssh` (and `sorcery-ssh-tui`), ensure the `git` user can read `/etc/sorcery/refresh-token`, and add the following to `sshd_config`: ```sshconfig Match User git SetEnv SORCERY_REPOSITORIES=/home/git/public SORCERY_SOCKET=/run/sorcery/sock SORCERY_REFRESH_TOKEN_FILE=/etc/sorcery/refresh-token SORCERY_CLONE_URL_BASE=https://my-cool-git.example SORCERY_INSTANCE_NAME=my-cool-git.example SORCERY_SSH_TUI=/usr/local/bin/sorcery-ssh-tui ForceCommand /usr/local/bin/sorcery-ssh ``` ## optional: push refresh since this is a static-files-based viewer, repositories need updating when their state changes. if you're using `sorcery-ssh`, repositories will automatically refresh after a `git receive-pack`. otherwise, you can use a post-receive hook like so: ```sh #!/usr/bin/env sh repo=$(basename "$PWD" .git) user=$(basename "$(dirname "$PWD")") token=$(cat /etc/sorcery/refresh-token) exec curl -fsS --unix-socket /run/sorcery/sock \ -H "Authorization: Bearer $token" \ -X POST "https://my-cool-git.example/-/refresh/$user/$repo" ``` in any case, sorceryd's scanner will pick changes up eventually, so this is optional ## development ```sh cd web && deno task check && deno task test && deno task build cd .. && cargo test ``` since we embed the frontend inside the executable, you **must** generate the frontend bundle before running a `cargo build`.