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	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	let GroupId = Parameter
41		.get("groupId")
42		.or_else(|| Parameter.get("group_id"))
43		.and_then(Value::as_str)
44		.unwrap_or("")
45		.to_string();
46	let Label = Parameter.get("label").and_then(Value::as_str).unwrap_or(&GroupId).to_string();
47
48	if GroupId.is_empty() {
49		dev_log!("provider-register", "[ProviderRegister] scm-group skip: missing group_id");
50		return;
51	}
52
53	// Seed the group through the trait so subsequent `update_scm_group`
54	// calls can locate it. UpdateSourceControlGroup is an upsert - it
55	// creates the entry on first call - so this primes state without
56	// requiring a separate "create-group" trait method. Field names
57	// must match `SourceControlGroupUpdateDTO`'s camelCase wire shape
58	// (post-DTO-audit): `providerHandle`, `groupId`, `label`.
59	let GroupData = json!({
60		"providerHandle": ScmHandle,
61		"groupId": &GroupId,
62		"label": &Label,
63		"resourceStates": [],
64	});
65	if let Err(Error) = Service
66		.RunTime()
67		.Environment
68		.UpdateSourceControlGroup(ScmHandle, GroupData)
69		.await
70	{
71		dev_log!(
72			"grpc",
73			"warn: [Scm] UpdateSourceControlGroup (seed) failed scm={} group={}: {}",
74			ScmHandle,
75			GroupId,
76			Error
77		);
78	}
79
80	let _ = Service.ApplicationHandle().emit(
81		"sky://scm/registerGroup",
82		json!({
83			"scmHandle": ScmHandle,
84			"groupHandle": &GroupHandleStr,
85			"groupId": &GroupId,
86			"label": &Label,
87		}),
88	);
89
90	dev_log!(
91		"grpc",
92		"[Scm] register group scm_handle={} group_id={} label={}",
93		ScmHandle,
94		GroupId,
95		Label
96	);
97}