Coverage Report

Created: 2026-09-13 01:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/runner/work/lyquor/lyquor/toolchain/shaker/src/publish.rs
Line
Count
Source
1
use anyhow::Context;
2
use lyquor_oci::OciArtifact;
3
use lyquor_oci::pack::LyquidPack;
4
use lyquor_oci::registry::{ClientProtocol, OCIReference, OCIRegistryClient, Reference as RegistryReference};
5
use lyquor_primitives::B256;
6
use reqwest::Url;
7
8
/// Pushes a Lyquid pack to an OCI registry reference and returns its digest.
9
2
pub async fn push_lyquid(
10
2
    pack: LyquidPack, registry: &OCIRegistryClient, reference: &OCIReference,
11
2
) -> anyhow::Result<B256> {
12
2
    let artifact = OciArtifact::try_from(pack)
?0
;
13
2
    let digest = registry.push_reference(&artifact, reference).await
?0
;
14
2
    Ok(*digest.digest())
15
2
}
16
17
/// Pushes a Lyquid pack to the local registry derived from a node API endpoint.
18
0
pub async fn push_lyquid_to_endpoint(pack: LyquidPack, endpoint: &str) -> anyhow::Result<B256> {
19
0
    let reference = local_oci_target_from_api_endpoint(endpoint)?;
20
0
    let oci = crate::oci_registry_from_reference(&reference, None, None, None);
21
0
    push_lyquid(pack, &oci, reference.reference()).await
22
0
}
23
24
4
fn local_oci_target_from_api_endpoint(endpoint: &str) -> anyhow::Result<RegistryReference> {
25
4
    let url = Url::parse(endpoint).with_context(|| 
format!0
("Invalid node API endpoint `{endpoint}`"))
?0
;
26
4
    let registry = registry_host_from_api_endpoint(&url)
?0
;
27
4
    let reference = OCIReference::with_tag(registry, "lyquids/local".into(), "latest".into());
28
4
    let transport = match url.scheme() {
29
4
        "http" | 
"ws"3
=>
ClientProtocol::Http3
,
30
1
        "https" | "wss" => ClientProtocol::Https,
31
0
        scheme => anyhow::bail!("Unsupported node API endpoint scheme `{scheme}`"),
32
    };
33
4
    Ok(RegistryReference::new(reference, transport))
34
4
}
35
36
4
fn registry_host_from_api_endpoint(url: &Url) -> anyhow::Result<String> {
37
4
    let host = url.host_str().context("Node API endpoint is missing a host")
?0
;
38
4
    let host = if host.contains(':') {
39
0
        format!("[{host}]")
40
    } else {
41
4
        host.to_owned()
42
    };
43
4
    let port = url
44
4
        .port_or_known_default()
45
4
        .context("Node API endpoint is missing a port and has no known default")
?0
;
46
4
    Ok(format!("{host}:{port}"))
47
4
}
48
49
#[cfg(test)]
50
mod tests {
51
    use super::*;
52
    use lyquor_test::test;
53
54
    #[test]
55
    fn local_reference_derives_target_from_supported_endpoint_forms() {
56
        let cases = [
57
            (
58
                "ws://127.0.0.1:10087/ws",
59
                "127.0.0.1:10087/lyquids/local:latest",
60
                ClientProtocol::Http,
61
            ),
62
            (
63
                "http://localhost:10087/api",
64
                "localhost:10087/lyquids/local:latest",
65
                ClientProtocol::Http,
66
            ),
67
            ("ws://lyquor/ws", "lyquor:80/lyquids/local:latest", ClientProtocol::Http),
68
            (
69
                "wss://lyquor/ws",
70
                "lyquor:443/lyquids/local:latest",
71
                ClientProtocol::Https,
72
            ),
73
        ];
74
75
        for (endpoint, expected_reference, expected_transport) in cases {
76
            let reference = local_oci_target_from_api_endpoint(endpoint).unwrap();
77
            assert_eq!(reference.reference().to_string(), expected_reference);
78
            assert_eq!(reference.protocol(), expected_transport);
79
        }
80
    }
81
}