Something went wrong. Try again.
A human-friendly DSL for ATProto Lexicons forked from stavola.xyz/mlf
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128//! `mlf status` — show each NSID's state (new / changed / unchanged ///! removed) relative to what's currently published on the PDS, plus the//! DNS readiness of each authority in the package.
use crate::remote_state::{ AuthorityStatus, Classification, RemoteState, RemoteStateError, classify,};
pub async fn run_status() -> Result<(), RemoteStateError> { let state = RemoteState::load().await?;
println!("Package: {}", state.package.name); match state.publishing_did.as_deref() { Some(did) => println!("Publishing DID: {did}"), None => println!("Publishing DID: (not yet set — _lexicon TXT records missing)"), } if let Some(pds) = state.pds.as_deref() { println!("PDS: {pds}"); } println!();
print_dns_section(&state); println!(); print_lexicon_section(&state);
Ok(())}
fn print_dns_section(state: &RemoteState) { println!("DNS authority readiness:"); if state.authority_status.is_empty() { println!(" (no authorities found — is your workspace empty?)"); return; } for (label, status) in &state.authority_status { match status { AuthorityStatus::Resolved { did } => { let matches_package = state .publishing_did .as_deref() .map(|p| p == did) .unwrap_or(false); let marker = if matches_package { "✓" } else { "≠" }; println!(" {marker} {label} → did={did}"); } AuthorityStatus::Missing => { println!(" ✗ {label} → (TXT record missing)"); } AuthorityStatus::Error(e) => { println!(" ! {label} → (lookup failed: {e})"); } } }}
fn print_lexicon_section(state: &RemoteState) { let classifications = classify(state);
if classifications.is_empty() { println!("No local lexicons found."); return; }
let mut new = Vec::new(); let mut changed = Vec::new(); let mut removed = Vec::new(); let mut unchanged = Vec::new(); for (nsid, cls) in &classifications { match cls { Classification::New => new.push(nsid), Classification::Changed { .. } => changed.push(nsid), Classification::Removed => removed.push(nsid), Classification::Unchanged => unchanged.push(nsid), } }
println!( "Lexicons: {} total ({} unchanged, {} changed, {} new, {} removed)", classifications.len(), unchanged.len(), changed.len(), new.len(), removed.len(), ); println!();
if !new.is_empty() { println!(" New (will be published):"); for nsid in new { if let Some(local) = state.local.get(nsid) { println!(" + {nsid} cid={}", local.cid); } } println!(); }
if !changed.is_empty() { println!(" Changed (will be republished):"); for nsid in changed { if let Some(Classification::Changed { local_cid, remote_cid, }) = classifications.get(nsid) { println!(" ~ {nsid} {remote_cid} → {local_cid}"); } } println!(); }
if !removed.is_empty() { println!(" Removed (will be unpublished):"); for nsid in removed { if let Some(remote) = state.remote.get(nsid) { println!(" - {nsid} cid={}", remote.cid); } } println!(); }
if !unchanged.is_empty() { println!(" Unchanged:"); for nsid in unchanged { println!(" = {nsid}"); } }}