forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

knotserver: add query lexicon for version

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li e262afed 6adfb3a9

verified
Changed files
+135 -54
api
tangled
knotserver
lexicons
nix
+30
api/tangled/knotversion.go
···
···
+
// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
+
+
package tangled
+
+
// schema: sh.tangled.knot.version
+
+
import (
+
"context"
+
+
"github.com/bluesky-social/indigo/lex/util"
+
)
+
+
const (
+
KnotVersionNSID = "sh.tangled.knot.version"
+
)
+
+
// KnotVersion_Output is the output of a sh.tangled.knot.version call.
+
type KnotVersion_Output struct {
+
Version string `json:"version" cborgen:"version"`
+
}
+
+
// KnotVersion calls the XRPC method "sh.tangled.knot.version".
+
func KnotVersion(ctx context.Context, c util.LexClient) (*KnotVersion_Output, error) {
+
var out KnotVersion_Output
+
if err := c.LexDo(ctx, util.Query, "", "sh.tangled.knot.version", nil, nil, &out); err != nil {
+
return nil, err
+
}
+
+
return &out, nil
+
}
+1 -53
knotserver/router.go
···
"fmt"
"log/slog"
"net/http"
-
"runtime/debug"
"github.com/go-chi/chi/v5"
"tangled.sh/tangled.sh/core/idresolver"
···
})
// xrpc apis
-
r.Route("/xrpc", func(r chi.Router) {
-
r.Get("/_health", h.Version)
-
r.Mount("/", h.XrpcRouter())
-
})
// Socket that streams git oplogs
r.Get("/events", h.Events)
···
ServiceAuth: serviceAuth,
}
return xrpc.Router()
-
}
-
-
// version is set during build time.
-
var version string
-
-
func (h *Knot) Version(w http.ResponseWriter, r *http.Request) {
-
if version == "" {
-
info, ok := debug.ReadBuildInfo()
-
if !ok {
-
http.Error(w, "failed to read build info", http.StatusInternalServerError)
-
return
-
}
-
-
var modVer string
-
var sha string
-
var modified bool
-
-
for _, mod := range info.Deps {
-
if mod.Path == "tangled.sh/tangled.sh/knotserver" {
-
modVer = mod.Version
-
break
-
}
-
}
-
-
for _, setting := range info.Settings {
-
switch setting.Key {
-
case "vcs.revision":
-
sha = setting.Value
-
case "vcs.modified":
-
modified = setting.Value == "true"
-
}
-
}
-
-
if modVer == "" {
-
modVer = "unknown"
-
}
-
-
if sha == "" {
-
version = modVer
-
} else if modified {
-
version = fmt.Sprintf("%s (%s with modifications)", modVer, sha)
-
} else {
-
version = fmt.Sprintf("%s (%s)", modVer, sha)
-
}
-
}
-
-
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-
fmt.Fprintf(w, "knotserver/%s", version)
}
func (h *Knot) configureOwner() error {
···
"fmt"
"log/slog"
"net/http"
"github.com/go-chi/chi/v5"
"tangled.sh/tangled.sh/core/idresolver"
···
})
// xrpc apis
+
r.Mount("/xrpc", h.XrpcRouter())
// Socket that streams git oplogs
r.Get("/events", h.Events)
···
ServiceAuth: serviceAuth,
}
return xrpc.Router()
}
func (h *Knot) configureOwner() error {
+70
knotserver/xrpc/version.go
···
···
+
package xrpc
+
+
import (
+
"encoding/json"
+
"fmt"
+
"net/http"
+
"runtime/debug"
+
+
"tangled.sh/tangled.sh/core/api/tangled"
+
xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors"
+
)
+
+
// version is set during build time.
+
var version string
+
+
func (x *Xrpc) Version(w http.ResponseWriter, r *http.Request) {
+
if version == "" {
+
info, ok := debug.ReadBuildInfo()
+
if !ok {
+
http.Error(w, "failed to read build info", http.StatusInternalServerError)
+
return
+
}
+
+
var modVer string
+
var sha string
+
var modified bool
+
+
for _, mod := range info.Deps {
+
if mod.Path == "tangled.sh/tangled.sh/knotserver/xrpc" {
+
modVer = mod.Version
+
break
+
}
+
}
+
+
for _, setting := range info.Settings {
+
switch setting.Key {
+
case "vcs.revision":
+
sha = setting.Value
+
case "vcs.modified":
+
modified = setting.Value == "true"
+
}
+
}
+
+
if modVer == "" {
+
modVer = "unknown"
+
}
+
+
if sha == "" {
+
version = modVer
+
} else if modified {
+
version = fmt.Sprintf("%s (%s with modifications)", modVer, sha)
+
} else {
+
version = fmt.Sprintf("%s (%s)", modVer, sha)
+
}
+
}
+
+
response := tangled.KnotVersion_Output{
+
Version: version,
+
}
+
+
w.Header().Set("Content-Type", "application/json")
+
if err := json.NewEncoder(w).Encode(response); err != nil {
+
x.Logger.Error("failed to encode response", "error", err)
+
writeError(w, xrpcerr.NewXrpcError(
+
xrpcerr.WithTag("InternalServerError"),
+
xrpcerr.WithMessage("failed to encode response"),
+
), http.StatusInternalServerError)
+
return
+
}
+
}
+1
knotserver/xrpc/xrpc.go
···
// knot query endpoints (no auth required)
r.Get("/"+tangled.KnotListKeysNSID, x.ListKeys)
// service query endpoints (no auth required)
r.Get("/"+tangled.OwnerNSID, x.Owner)
···
// knot query endpoints (no auth required)
r.Get("/"+tangled.KnotListKeysNSID, x.ListKeys)
+
r.Get("/"+tangled.KnotVersionNSID, x.Version)
// service query endpoints (no auth required)
r.Get("/"+tangled.OwnerNSID, x.Owner)
+25
lexicons/knot/version.json
···
···
+
{
+
"lexicon": 1,
+
"id": "sh.tangled.knot.version",
+
"defs": {
+
"main": {
+
"type": "query",
+
"description": "Get the version of a knot",
+
"output": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": [
+
"version"
+
],
+
"properties": {
+
"version": {
+
"type": "string"
+
}
+
}
+
}
+
},
+
"errors": []
+
}
+
}
+
}
+8 -1
nix/pkgs/knot-unwrapped.nix
···
sqlite-lib,
src,
}:
buildGoApplication {
pname = "knot";
-
version = "0.1.0";
inherit src modules;
doCheck = false;
subPackages = ["cmd/knot"];
tags = ["libsqlite3"];
env.CGO_CFLAGS = "-I ${sqlite-lib}/include ";
env.CGO_LDFLAGS = "-L ${sqlite-lib}/lib";
···
sqlite-lib,
src,
}:
+
let
+
version = "1.8.1-alpha";
+
in
buildGoApplication {
pname = "knot";
+
version = "1.8.1";
inherit src modules;
doCheck = false;
subPackages = ["cmd/knot"];
tags = ["libsqlite3"];
+
+
ldflags = [
+
"-X tangled.sh/tangled.sh/core/knotserver/xrpc.version=${version}"
+
];
env.CGO_CFLAGS = "-I ${sqlite-lib}/include ";
env.CGO_LDFLAGS = "-L ${sqlite-lib}/lib";