Skip to main content

Mountain/Vine/Server/Notification/
RegisterScmResourceGroup.rs

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