don't
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(knot): impl `sh.tangled.repo.tag` xrpc query

Signed-off-by: tjh <x@tjh.dev>

tjh c8522e63 8b0c3335

+65
+1
crates/gordian-knot/src/public/xrpc.rs
··· 38 38 .merge(sh_tangled::repo::merge_check()) 39 39 .merge(sh_tangled::repo::languages()) 40 40 .merge(sh_tangled::repo::log()) 41 + .merge(sh_tangled::repo::tag()) 41 42 .merge(sh_tangled::repo::tags()) 42 43 .merge(sh_tangled::repo::tree()) 43 44 .merge(sh_tangled::repo::set_default_branch())
+2
crates/gordian-knot/src/public/xrpc/sh_tangled/repo.rs
··· 16 16 pub mod log; 17 17 pub mod merge_check; 18 18 pub mod set_default_branch; 19 + pub mod tag; 19 20 pub mod tags; 20 21 pub mod tree; 21 22 ··· 55 54 impl_xrpc!(QUERY, get_default_branch, get_default_branch); 56 55 impl_xrpc!(QUERY, languages, languages); 57 56 impl_xrpc!(QUERY, log, log); 57 + impl_xrpc!(QUERY, tag, tag); 58 58 impl_xrpc!(QUERY, tags, tags); 59 59 impl_xrpc!(QUERY, tree, tree); 60 60
+47
crates/gordian-knot/src/public/xrpc/sh_tangled/repo/tag.rs
··· 1 + use core::error; 2 + 3 + use axum::Json; 4 + use serde::Serialize; 5 + 6 + use crate::extract::repository::XrpcRepository; 7 + use crate::lexicon::sh_tangled::repo::tag::Input; 8 + use crate::public::xrpc::XrpcError; 9 + use crate::public::xrpc::XrpcQuery; 10 + use crate::public::xrpc::XrpcResult; 11 + use crate::public::xrpc::sh_tangled::repo::tags::Tag; 12 + 13 + pub const LXM: &str = "/sh.tangled.repo.tag"; 14 + 15 + /// Output of `sh.tangled.repo.tag` query. 16 + /// 17 + /// This is not defined in the lexicon, but models what knotserver 18 + /// currently produces. 19 + #[derive(Debug, Serialize)] 20 + pub struct Output { 21 + pub tag: Tag, 22 + } 23 + 24 + #[tracing::instrument(target = "sh_tangled::repo::tags", err)] 25 + pub async fn handle( 26 + XrpcRepository(repository): XrpcRepository, 27 + XrpcQuery(Input { repo, tag }): XrpcQuery<Input>, 28 + ) -> XrpcResult<Json<Output>> { 29 + tokio_rayon::spawn(move || { 30 + let repository = repository.to_thread_local(); 31 + let reference = repository 32 + .find_reference(&format!("refs/tags/{tag}")) 33 + .map_err(TagNotFound)?; 34 + let tag = reference.try_into()?; 35 + Ok(Json(Output { tag }).into()) 36 + }) 37 + .await 38 + } 39 + 40 + struct TagNotFound<E>(E); 41 + 42 + impl<E: error::Error> From<TagNotFound<E>> for XrpcError { 43 + fn from(value: TagNotFound<E>) -> Self { 44 + use axum::http::StatusCode; 45 + Self::new(StatusCode::NOT_FOUND, "TagNotFound", value.0.to_string()) 46 + } 47 + }
+1
crates/gordian-lexicon/src/sh_tangled/repo.rs
··· 13 13 pub mod merge_check; 14 14 pub mod pull; 15 15 pub mod set_default_branch; 16 + pub mod tag; 16 17 pub mod tags; 17 18 pub mod tree; 18 19
+14
crates/gordian-lexicon/src/sh_tangled/repo/tag.rs
··· 1 + //! 2 + //! <https://tangled.org/@tangled.org/core/blob/master/lexicons/repo/tag.json> 3 + 4 + /// Parameters for the `sh.tangled.repo.tag` query. 5 + /// 6 + /// <https://tangled.org/@tangled.org/core/blob/master/lexicons/repo/tag.json> 7 + #[derive(Debug, serde::Deserialize)] 8 + pub struct Input { 9 + /// Repository identifier in the format `did:plc:.../repoName` 10 + pub repo: String, 11 + 12 + /// Name of tag, such as v1.3.0 13 + pub tag: String, 14 + }