noosphere_cli/native/commands/sphere/
status.rs1use std::collections::BTreeMap;
2
3use crate::native::{content::Content, Workspace};
4use anyhow::Result;
5use noosphere_core::context::{HasSphereContext, SphereCursor};
6use noosphere_core::data::ContentType;
7
8fn status_section(
9 name: &str,
10 entries: &BTreeMap<String, Option<ContentType>>,
11 section: &mut Vec<(String, String, String)>,
12 max_name_length: &mut usize,
13 max_content_type_length: &mut usize,
14) {
15 for (slug, content_type) in entries {
16 let content_type = content_type
17 .as_ref()
18 .map(|content_type| content_type.to_string())
19 .unwrap_or_else(|| "Unknown".into());
20
21 *max_name_length = *max_name_length.max(&mut slug.len());
22 *max_content_type_length = *max_content_type_length.max(&mut content_type.len());
23
24 section.push((slug.to_string(), content_type, String::from(name)));
25 }
26}
27
28pub async fn status(only_id: bool, workspace: &Workspace) -> Result<()> {
31 workspace.ensure_sphere_initialized()?;
32
33 let identity = workspace.sphere_identity().await?;
34
35 if only_id {
36 info!("{identity}");
37 return Ok(());
38 }
39
40 info!("This sphere's identity is {identity}");
41
42 let sphere_context = workspace.sphere_context().await?;
43 let cid = SphereCursor::latest(sphere_context).version().await?;
44 info!("The latest (saved) version of your sphere is {cid}\n");
45
46 let (_, content_changes, _) = match Content::read_changes(workspace).await? {
49 Some(changes) => changes,
50 None => {
51 info!("No new changes to sphere content!");
52 return Ok(());
53 }
54 };
55
56 info!("Here is a summary of the current changes to sphere content:\n");
57
58 let mut content = Vec::new();
59
60 let mut max_name_length = 7usize;
61 let mut max_content_type_length = 16usize;
62
63 status_section(
64 "Updated",
65 &content_changes.updated,
66 &mut content,
67 &mut max_name_length,
68 &mut max_content_type_length,
69 );
70
71 status_section(
72 "New",
73 &content_changes.new,
74 &mut content,
75 &mut max_name_length,
76 &mut max_content_type_length,
77 );
78
79 status_section(
80 "Removed",
81 &content_changes.removed,
82 &mut content,
83 &mut max_name_length,
84 &mut max_content_type_length,
85 );
86
87 if !content.is_empty() {
88 info!(
89 "{:max_name_length$} {:max_content_type_length$} STATUS",
90 "NAME", "CONTENT-TYPE"
91 );
92
93 for (slug, content_type, status) in content {
94 info!("{slug:max_name_length$} {content_type:max_content_type_length$} {status}");
95 }
96 } else {
97 info!("No content has changed since the last save!")
98 }
99
100 Ok(())
101}