Skip to main content

Mountain/Vine/Server/Notification/
RegisterScmResourceGroup.rs

1//! Cocoon → Mountain `register_scm_resource_group` notification.
2//!
3//! Pairs with `RegisterScmProvider`: an SCM provider creates one or more
4//! resource groups (Git's "Changes", "Staged Changes", "Merge Changes").
5//! Cocoon emits this from `ScmNamespace.ts:42` whenever
6//! `sourceControl.createResourceGroup(id, label)` is called by an
7//! extension. Wire payload:
8//!
9//! ```ignore
10//! { scm_handle, group_handle, group_id, label }
11//! ```
12//!
13//! The renderer SCM view subscribes to `sky://scm/registerGroup` to
14//! materialise the group header row; the typed
15//! `SourceControlManagementProvider::UpdateSourceControlGroup` trait
16//! seeds the group with an empty `resourceStates` list so the
17//! state-tracking path is also primed for the first `update_scm_group`
18//! that follows.
19
20use serde_json::{Value, json};
21use tauri::Emitter;
22use CommonLibrary::SourceControlManagement::SourceControlManagementProvider::SourceControlManagementProvider;
23
24use crate::{Vine::Server::MountainVinegRPCService::MountainVinegRPCService, dev_log};
25
26pub async fn RegisterScmResourceGroup(Service:&MountainVinegRPCService, Parameter:&Value) {
27	// Producer (Cocoon `ScmNamespace.ts`) emits camelCase keys post-audit.
28	let ScmHandle = Parameter
29		.get("scmHandle")
30		.or_else(|| Parameter.get("scm_handle"))
31		.and_then(Value::as_u64)
32		.unwrap_or(0) as u32;
33
34	let GroupHandleStr = Parameter
35		.get("groupHandle")
36		.or_else(|| Parameter.get("group_handle"))
37		.and_then(Value::as_str)
38		.unwrap_or("")
39		.to_string();
40
41	let GroupId = Parameter
42		.get("groupId")
43		.or_else(|| Parameter.get("group_id"))
44		.and_then(Value::as_str)
45		.unwrap_or("")
46		.to_string();
47
48	let Label = Parameter.get("label").and_then(Value::as_str).unwrap_or(&GroupId).to_string();
49
50	if GroupId.is_empty() {
51		dev_log!("provider-register", "[ProviderRegister] scm-group skip: missing group_id");
52
53		return;
54	}
55
56	// Seed the group through the trait so subsequent `update_scm_group`
57	// calls can locate it. UpdateSourceControlGroup is an upsert - it
58	// creates the entry on first call - so this primes state without
59	// requiring a separate "create-group" trait method. Field names
60	// must match `SourceControlGroupUpdateDTO`'s camelCase wire shape
61	// (post-DTO-audit): `providerHandle`, `groupId`, `label`.
62	let GroupData = json!({
63		"providerHandle": ScmHandle,
64		"groupId": &GroupId,
65		"label": &Label,
66		"resourceStates": [],
67	});
68
69	if let Err(Error) = Service
70		.RunTime()
71		.Environment
72		.UpdateSourceControlGroup(ScmHandle, GroupData)
73		.await
74	{
75		dev_log!(
76			"grpc",
77			"warn: [Scm] UpdateSourceControlGroup (seed) failed scm={} group={}: {}",
78			ScmHandle,
79			GroupId,
80			Error
81		);
82	}
83
84	let _ = Service.ApplicationHandle().emit(
85		"sky://scm/registerGroup",
86		json!({
87			"scmHandle": ScmHandle,
88			"groupHandle": &GroupHandleStr,
89			"groupId": &GroupId,
90			"label": &Label,
91		}),
92	);
93
94	dev_log!(
95		"grpc",
96		"[Scm] register group scm_handle={} group_id={} label={}",
97		ScmHandle,
98		GroupId,
99		Label
100	);
101}