Skip to content

Commit eba2812

Browse files
authored
Merge branch 'main' into ref/buck2
2 parents 9c700af + 7388990 commit eba2812

10 files changed

Lines changed: 988 additions & 591 deletions

File tree

ceres/src/api_service/commit_ops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ pub async fn traverse_history_commits<T: ApiHandler + ?Sized>(
459459
}
460460

461461
/// Collect all blobs as (path, ObjectHash) pairs under a commit tree
462-
async fn collect_commit_blobs<T: ApiHandler + ?Sized>(
462+
pub async fn collect_commit_blobs<T: ApiHandler + ?Sized>(
463463
handler: &T,
464464
commit: &Commit,
465465
) -> Result<Vec<(PathBuf, ObjectHash)>, GitError> {

ceres/src/api_service/mono_api_service.rs

Lines changed: 31 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ use async_trait::async_trait;
4848
use bellatrix::Bellatrix;
4949
use bytes::Bytes;
5050
use callisto::{
51-
entity_ext::generate_link,
5251
mega_cl, mega_refs, mega_tag, mega_tree,
5352
sea_orm_active_enums::{ConvTypeEnum, MergeStatusEnum, QueueFailureTypeEnum, QueueStatusEnum},
5453
};
@@ -91,14 +90,14 @@ use crate::{
9190
ApiHandler, buck_tree_builder::BuckCommitBuilder, cache::GitObjectCache,
9291
state::ProtocolApiState, tree_ops,
9392
},
94-
build_trigger::BuildTriggerService,
93+
code_edit::{on_edit::OneditCodeEdit, utils as edit_utils},
9594
model::{
9695
buck::{
9796
CompletePayload, CompleteResponse, DEFAULT_MODE, FileChange,
9897
FileToUpload as ApiFileToUpload, ManifestPayload, ManifestResponse,
9998
},
10099
change_list::{ClDiffFile, UpdateBranchStatusRes},
101-
git::{CreateEntryInfo, EditCLMode, EditFilePayload, EditFileResult},
100+
git::{CreateEntryInfo, EditFilePayload, EditFileResult},
102101
tag::TagInfo,
103102
third_party::{ThirdPartyClient, ThirdPartyRepoTrait},
104103
},
@@ -376,6 +375,8 @@ impl ApiHandler for MonoApiService {
376375

377376
/// Save file edit in monorepo with optimistic concurrency check
378377
async fn save_file_edit(&self, payload: EditFilePayload) -> Result<EditFileResult, GitError> {
378+
let repo_path = "/";
379+
let src_commit = edit_utils::get_repo_latest_commit(&self.storage, repo_path).await?;
379380
let file_path = PathBuf::from(&payload.path);
380381
let parent_path = file_path
381382
.parent()
@@ -414,12 +415,13 @@ impl ApiHandler for MonoApiService {
414415
.clone()
415416
.unwrap_or("Anonymous".to_string());
416417

417-
let cl = self
418+
let editor = OneditCodeEdit::from(repo_path, &src_commit.id.to_string(), &self);
419+
let cl = editor
418420
.find_or_create_cl_for_edit(
421+
&self.storage,
422+
&editor,
419423
payload.mode,
420424
&new_commit_id,
421-
&payload.commit_message,
422-
&payload.path,
423425
&username,
424426
)
425427
.await?;
@@ -429,13 +431,13 @@ impl ApiHandler for MonoApiService {
429431
.await?;
430432

431433
if !payload.skip_build {
432-
self.trigger_build_for_cl(&cl.link).await?;
434+
self.trigger_build_for_cl(&editor, &cl, &username).await?;
433435
}
434436

435437
Ok(EditFileResult {
436438
commit_id: new_commit_id,
437439
new_oid: new_blob.id.to_string(),
438-
path: payload.path,
440+
path: repo_path.to_string(),
439441
cl_link: Some(cl.link),
440442
})
441443
}
@@ -1057,127 +1059,24 @@ impl MonoApiService {
10571059
}
10581060
}
10591061

1060-
async fn create_new_cl(
1062+
async fn trigger_build_for_cl(
10611063
&self,
1062-
repo_path: &str,
1063-
commit_message: &str,
1064-
to_hash: &str,
1065-
username: &str,
1066-
) -> Result<mega_cl::Model, GitError> {
1067-
let cl_link = generate_link();
1068-
1069-
let from_hash = self
1070-
.storage
1071-
.mono_storage()
1072-
.get_main_ref(repo_path)
1073-
.await?
1074-
.ok_or_else(|| MegaError::Other("Main ref not found".to_string()))?
1075-
.ref_commit_hash;
1076-
1077-
// Create and return a new CL model
1078-
let cl = self
1079-
.storage
1080-
.cl_storage()
1081-
.new_cl_model(
1082-
repo_path,
1083-
&cl_link,
1084-
commit_message,
1085-
&from_hash,
1086-
to_hash,
1087-
username,
1088-
)
1089-
.await
1090-
.map_err(|e| GitError::CustomError(format!("Failed to create CL: {}", e)))?;
1091-
1092-
Ok(cl)
1093-
}
1094-
1095-
/// Finds or creates a Change List (CL) for file edits.
1096-
/// This method determines whether to create a new CL or reuse an existing one based on the
1097-
/// [`EditCLMode`] passed in `mode`. For example, `EditCLMode::ForceCreate` will always create
1098-
/// a new CL, while `EditCLMode::TryReuse` will attempt to find an open CL for the given user
1099-
/// and path and only create a new one if none exists.
1100-
///
1101-
/// # Arguments
1102-
/// * `mode` - Controls whether to force creation of a new CL (`ForceCreate`) or try to reuse an
1103-
/// existing open CL for the user and path when possible (`TryReuse`).
1104-
/// * `to_hash` - The commit hash representing the new state after the edit.
1105-
/// * `commit_message` - The message describing the changes made in the CL.
1106-
/// * `file_path` - The path of the file being edited.
1107-
/// * `username` - The username of the user performing the edit.
1108-
///
1109-
/// # Returns
1110-
/// A `Result` containing the `mega_cl::Model` representing the found or created CL on success,
1111-
/// or a `GitError` on failure.
1112-
async fn find_or_create_cl_for_edit(
1113-
&self,
1114-
mode: EditCLMode,
1115-
to_hash: &str,
1116-
commit_message: &str,
1117-
file_path: &str,
1064+
editor: &OneditCodeEdit,
1065+
cl: &mega_cl::Model,
11181066
username: &str,
1119-
) -> Result<mega_cl::Model, GitError> {
1120-
let path = PathBuf::from(file_path);
1121-
let repo_path = path
1122-
.parent()
1123-
.map(|p| p.to_string_lossy().to_string())
1124-
.unwrap_or_else(|| "/".to_string());
1125-
1126-
let storage = self.storage.cl_storage();
1127-
match mode {
1128-
EditCLMode::ForceCreate => {
1129-
self.create_new_cl(&repo_path, commit_message, to_hash, username)
1130-
.await
1131-
}
1132-
EditCLMode::TryReuse(None) => {
1133-
if let Some(existing_cl) =
1134-
storage
1135-
.get_open_cl_by_path(&repo_path, username)
1136-
.await
1137-
.map_err(|e| GitError::CustomError(format!("Failed to fetch CL: {}", e)))?
1138-
{
1139-
storage
1140-
.update_cl_to_hash(existing_cl.clone(), to_hash)
1141-
.await?;
1142-
Ok(existing_cl)
1143-
} else {
1144-
self.create_new_cl(&repo_path, commit_message, to_hash, username)
1145-
.await
1146-
}
1147-
}
1148-
EditCLMode::TryReuse(Some(link)) => {
1149-
match self.storage.cl_storage().get_cl(&link).await {
1150-
Ok(Some(model)) => {
1151-
storage.update_cl_to_hash(model.clone(), to_hash).await?;
1152-
Ok(model)
1153-
}
1154-
_ => {
1155-
self.create_new_cl(&repo_path, commit_message, to_hash, username)
1156-
.await
1157-
}
1158-
}
1159-
}
1160-
}
1161-
}
1162-
1163-
/// Triggers a build for the specified CL in a background task.
1164-
///
1165-
/// This is a best-effort operation: the build runs asynchronously to keep the API responsive,
1166-
/// and any failures are logged but do not propagate to the caller.
1167-
async fn trigger_build_for_cl(&self, cl_link: &str) -> Result<(), GitError> {
1067+
) -> Result<(), GitError> {
11681068
let config = self.storage.config();
1169-
let bellatrix = Arc::new(Bellatrix::new(config.build.clone()));
1170-
let storage = self.storage.clone();
1069+
let bellatrix = Bellatrix::new(config.build.clone());
11711070
let git_cache = self.git_object_cache.clone();
1172-
let cl_link = cl_link.to_string();
1173-
1174-
// Spawn a background task to handle the build process
1175-
tokio::spawn(async move {
1176-
let service = BuildTriggerService::new(storage, git_cache, bellatrix);
1177-
if let Err(e) = service.trigger_for_cl(&cl_link).await {
1178-
tracing::warn!("Build trigger failed for CL {}: {}", cl_link, e);
1179-
}
1180-
});
1071+
editor
1072+
.trigger_build_and_check(
1073+
self.storage.clone(),
1074+
git_cache,
1075+
Arc::new(bellatrix),
1076+
cl,
1077+
username,
1078+
)
1079+
.await?;
11811080

11821081
Ok(())
11831082
}
@@ -2064,8 +1963,7 @@ impl MonoApiService {
20641963
.map_err(|e| GitError::CustomError(format!("Failed to get new commit blobs: {e}")))?;
20651964

20661965
// calculate pages
2067-
let sorted_changed_files = self
2068-
.cl_files_list(old_blobs.clone(), new_blobs.clone())
1966+
let sorted_changed_files = edit_utils::cl_files_list(old_blobs.clone(), new_blobs.clone())
20691967
.await
20701968
.map_err(|e| GitError::CustomError(e.to_string()))?;
20711969

@@ -2171,9 +2069,8 @@ impl MonoApiService {
21712069
let new_files = self.get_commit_blobs(&cl.to_hash.clone()).await?;
21722070

21732071
// calculate pages
2174-
let sorted_changed_files = self
2175-
.cl_files_list(old_files.clone(), new_files.clone())
2176-
.await?;
2072+
let sorted_changed_files =
2073+
edit_utils::cl_files_list(old_files.clone(), new_files.clone()).await?;
21772074
let file_paths: Vec<String> = sorted_changed_files
21782075
.iter()
21792076
.map(|f| f.path().to_string_lossy().to_string())
@@ -2277,8 +2174,7 @@ impl MonoApiService {
22772174
.get_commit_blobs(&cl.to_hash)
22782175
.await
22792176
.map_err(|e| GitError::CustomError(e.to_string()))?;
2280-
let cl_changed = self
2281-
.cl_files_list(old_blobs.clone(), new_blobs.clone())
2177+
let cl_changed = edit_utils::cl_files_list(old_blobs.clone(), new_blobs.clone())
22822178
.await
22832179
.map_err(|e| GitError::CustomError(e.to_string()))?;
22842180

@@ -2370,17 +2266,15 @@ impl MonoApiService {
23702266
.get_commit_blobs(&cl.to_hash)
23712267
.await
23722268
.map_err(|e| GitError::CustomError(e.to_string()))?;
2373-
let cl_changed = self
2374-
.cl_files_list(old_blobs.clone(), new_blobs.clone())
2269+
let cl_changed = edit_utils::cl_files_list(old_blobs.clone(), new_blobs.clone())
23752270
.await
23762271
.map_err(|e| GitError::CustomError(e.to_string()))?;
23772272

23782273
let target_blobs = self
23792274
.get_commit_blobs(target_head)
23802275
.await
23812276
.map_err(|e| GitError::CustomError(e.to_string()))?;
2382-
let base_vs_target = self
2383-
.cl_files_list(old_blobs.clone(), target_blobs.clone())
2277+
let base_vs_target = edit_utils::cl_files_list(old_blobs.clone(), target_blobs.clone())
23842278
.await
23852279
.map_err(|e| GitError::CustomError(e.to_string()))?;
23862280

@@ -2401,34 +2295,7 @@ impl MonoApiService {
24012295
old_files: Vec<(PathBuf, ObjectHash)>,
24022296
new_files: Vec<(PathBuf, ObjectHash)>,
24032297
) -> Result<Vec<ClDiffFile>, MegaError> {
2404-
let old_files: HashMap<PathBuf, ObjectHash> = old_files.into_iter().collect();
2405-
let new_files: HashMap<PathBuf, ObjectHash> = new_files.into_iter().collect();
2406-
let unions: HashSet<PathBuf> = old_files.keys().chain(new_files.keys()).cloned().collect();
2407-
let mut res = vec![];
2408-
for path in unions {
2409-
let old_hash = old_files.get(&path);
2410-
let new_hash = new_files.get(&path);
2411-
match (old_hash, new_hash) {
2412-
(None, None) => {}
2413-
(None, Some(new)) => res.push(ClDiffFile::New(path, *new)),
2414-
(Some(old), None) => res.push(ClDiffFile::Deleted(path, *old)),
2415-
(Some(old), Some(new)) => {
2416-
if old == new {
2417-
continue;
2418-
} else {
2419-
res.push(ClDiffFile::Modified(path, *old, *new));
2420-
}
2421-
}
2422-
}
2423-
}
2424-
2425-
// Sort the results
2426-
res.sort_by(|a, b| {
2427-
a.path()
2428-
.cmp(b.path())
2429-
.then_with(|| a.kind_weight().cmp(&b.kind_weight()))
2430-
});
2431-
Ok(res)
2298+
edit_utils::cl_files_list(old_files, new_files).await
24322299
}
24332300

24342301
pub async fn get_commit_blobs(

ceres/src/build_trigger/service.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ impl BuildTriggerService {
9999
Ok(Some(id))
100100
}
101101

102+
pub async fn build_by_context(
103+
storage: Storage,
104+
git_cache: Arc<GitObjectCache>,
105+
bellatrix: Arc<Bellatrix>,
106+
context: TriggerContext,
107+
) -> Result<Option<i64>, MegaError> {
108+
if !bellatrix.enable_build() {
109+
return Ok(None);
110+
}
111+
let registry = TriggerRegistry::new(storage, git_cache, bellatrix);
112+
113+
let id = registry.trigger_build(context).await?;
114+
Ok(Some(id))
115+
}
116+
102117
/// Triggers a build for an existing CL using its unique link.
103118
pub async fn trigger_for_cl(&self, cl_link: &str) -> Result<Option<i64>, MegaError> {
104119
if !self.is_enabled() {

ceres/src/code_edit/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub mod model;
2+
pub mod on_edit;
3+
pub mod on_push;
4+
pub mod utils;

0 commit comments

Comments
 (0)