-- SPDX-FileCopyrightText: © 2022—2026 Vladimir Zorin -- SPDX-License-Identifier: LicenseRef-OWL-1.0-or-later -- Licensed under OWL v1.0+. See LICENSE. --[[ lilgit: a read-only git HTTP(S) frontend. Serves `git clone`/`fetch` over smart-HTTP (via `http.git`) plus a browsing UI — repo index, directory trees at any ref, markdown/djot rendered as HTML, raw file serving — everything straight from the git object database. Bare repositories work; no worktree is ever needed. Runs standalone (own TLS via the `ssl` server config) or behind a reverse-proxy vhost. Single process. Repo discovery happens at startup; object and ref content is always fresh because the git core's mtime caches invalidate themselves, so pushes to existing repos appear immediately. ]] local std = require("std") local ws = require("http.server") local http_git = require("http.git") local config = require("lilgit.config") local repos = require("lilgit.repos") local render = require("lilgit.render") local handle = require("lilgit.handle") local cache = require("lilgit.cache") -- Kept in sync with lilpack.json manually: the compiled binary carries -- no manifest at runtime. local VERSION = "0.3.0" local run = function(self) local logger = self.__state.logger local names = {} for _, repo in ipairs(self.__state.registry.ordered) do names[#names + 1] = repo.name end logger:log({ msg = "lilgit serving", ip = self.cfg.ip, port = self.cfg.port, repos = table.concat(names, ","), }) return self.__state.srv:serve() end local new = function(cfg_override) local cfg, err = config.load(cfg_override) if not cfg then return nil, err end local logger = std.logger.new(cfg.log_level) local registry, r_err = repos.discover(cfg, logger) if not registry then return nil, r_err end -- Built once at startup: fails fast on a broken repo. local git_handle, g_err = http_git.serve(registry.prefix_map) if not git_handle then return nil, g_err end local state = { cfg = cfg, registry = registry, git_handle = git_handle, version = VERSION, templates = render.build_templates(cfg), md_cache = cfg.markdown_cache > 0 and cache.new(cfg.markdown_cache) or nil, } local srv, s_err = ws.new(cfg, handle.new(state)) if not srv then return nil, s_err end local instance = { cfg = cfg, __state = { logger = logger, registry = registry, srv = srv, }, run = run, } return instance end return { new = new, VERSION = VERSION, }