Skip to content

Commit e37c71d

Browse files
Acfboygenedna
andauthored
Integrated Buck2-Change-Detector to orion-server and orion workflow (#1721)
* feat: integrate buck2-change-detector into orion build progress Signed-off-by: Acfboy <acfboyu@outlook.com> * fix: some implementation issues Signed-off-by: Acfboy <acfboyu@outlook.com> * fix: clippy Signed-off-by: Acfboy <acfboyu@outlook.com> --------- Signed-off-by: Acfboy <acfboyu@outlook.com> Co-authored-by: Quanyi Ma <eli@patch.sh>
1 parent f3442c6 commit e37c71d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+8350
-65
lines changed

ceres/src/model/change_list.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ pub struct ClFilesRes {
140140

141141
impl From<ClDiffFile> for ClFilesRes {
142142
fn from(value: ClDiffFile) -> Self {
143+
// if change, please modify `ceres/src/pack/monorepo.rs` also.
143144
match value {
144145
ClDiffFile::New(path, sha) => Self {
145146
path: path.to_string_lossy().to_string(),

ceres/src/model/cl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

ceres/src/model/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod blame;
22
pub mod buck;
33
pub mod change_list;
4+
pub mod cl;
45
pub mod commit;
56
pub mod conversation;
67
pub mod dynamic_sidebar;

ceres/src/pack/monorepo.rs

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ use std::{
1313
use tokio::sync::{RwLock, mpsc};
1414
use tokio_stream::wrappers::ReceiverStream;
1515

16-
use bellatrix::{Bellatrix, orion_client::BuildInfo, orion_client::OrionBuildRequest};
16+
use bellatrix::{
17+
Bellatrix,
18+
orion_client::OrionBuildRequest,
19+
orion_client::{BuildInfo, ProjectRelativePath, Status},
20+
};
1721
use callisto::{
1822
entity_ext::generate_link, mega_cl, mega_refs, raw_blob, sea_orm_active_enums::ConvTypeEnum,
1923
};
@@ -587,6 +591,29 @@ impl MonoRepo {
587591
let mono_stg = self.storage.mono_storage();
588592
let mono_api_service: MonoApiService = self.into();
589593

594+
let mut path = Some(cl_path);
595+
let mut path_q = Vec::new();
596+
while let Some(p) = path {
597+
path_q.push(p);
598+
path = p.parent();
599+
}
600+
if path_q.len() > 2 {
601+
path_q.pop();
602+
path_q.pop();
603+
604+
let p = path_q[path_q.len() - 1];
605+
if p.parent().is_some()
606+
&& let Some(tree) = tree_ops::search_tree_by_path(&mono_api_service, p, None)
607+
.await
608+
.ok()
609+
.flatten()
610+
&& let Some(buck) = self.try_extract_buck(tree, cl_path)
611+
{
612+
return Ok(vec![buck]);
613+
};
614+
return Ok(vec![]);
615+
}
616+
590617
let mut search_trees: Vec<(PathBuf, Tree)> = vec![];
591618

592619
let diff_trees = self.diff_trees_from_cl().await?;
@@ -608,23 +635,6 @@ impl MonoRepo {
608635
}
609636
}
610637

611-
// no buck file found
612-
if res.is_empty() {
613-
let mut path = Some(cl_path);
614-
while let Some(p) = path {
615-
if p.parent().is_some()
616-
&& let Some(tree) = tree_ops::search_tree_by_path(&mono_api_service, p, None)
617-
.await
618-
.ok()
619-
.flatten()
620-
&& let Some(buck) = self.try_extract_buck(tree, cl_path)
621-
{
622-
return Ok(vec![buck]);
623-
};
624-
625-
path = p.parent();
626-
}
627-
}
628638
Ok(res)
629639
}
630640

@@ -910,7 +920,38 @@ impl MonoRepo {
910920
self.path
911921
);
912922
} else {
923+
let old_files = self.get_commit_blobs(&cl_info.from_hash).await?;
924+
let new_files = self.get_commit_blobs(&cl_info.to_hash).await?;
925+
let cl_diff_files = self.cl_files_list(old_files, new_files.clone()).await?;
926+
927+
let cl_base = PathBuf::from(&cl_info.path);
928+
let changes = cl_diff_files
929+
.into_iter()
930+
.map(|m| {
931+
let mut item: crate::model::change_list::ClFilesRes = m.into();
932+
item.path = cl_base.join(item.path).to_string_lossy().to_string();
933+
item
934+
})
935+
.collect::<Vec<_>>();
936+
913937
for buck_file in buck_files {
938+
let path_str = buck_file.path.to_str().expect("path is not valid UTF-8");
939+
let counter_changes: Vec<_> = changes
940+
.iter()
941+
.filter(|&s| PathBuf::from(&s.path).starts_with(&buck_file.path))
942+
.map(|s| {
943+
let path = ProjectRelativePath::from_abs(&s.path, path_str).unwrap();
944+
if s.action == "new" {
945+
Status::Added(path)
946+
} else if s.action == "deleted" {
947+
Status::Removed(path)
948+
} else if s.action == "modified" {
949+
Status::Modified(path)
950+
} else {
951+
unreachable!()
952+
}
953+
})
954+
.collect();
914955
let req = OrionBuildRequest {
915956
repo: buck_file.path.to_str().unwrap().to_string(),
916957
cl_link: link.to_string(),
@@ -921,6 +962,7 @@ impl MonoRepo {
921962
buck_hash: buck_file.buck.to_string(),
922963
buckconfig_hash: buck_file.buck_config.to_string(),
923964
args: Some(vec![]),
965+
changes: counter_changes,
924966
}],
925967
};
926968
let bellatrix = self.bellatrix.clone();
@@ -935,6 +977,23 @@ impl MonoRepo {
935977
check_reg.run_checks(cl_info.clone().into()).await?;
936978
Ok(())
937979
}
980+
981+
pub async fn get_commit_blobs(
982+
&self,
983+
commit_hash: &str,
984+
) -> Result<Vec<(PathBuf, SHA1)>, MegaError> {
985+
let api_service: MonoApiService = self.into();
986+
api_service.get_commit_blobs(commit_hash).await
987+
}
988+
989+
pub async fn cl_files_list(
990+
&self,
991+
old_files: Vec<(PathBuf, SHA1)>,
992+
new_files: Vec<(PathBuf, SHA1)>,
993+
) -> Result<Vec<crate::model::change_list::ClDiffFile>, MegaError> {
994+
let api_service: MonoApiService = self.into();
995+
api_service.cl_files_list(old_files, new_files).await
996+
}
938997
}
939998

940999
type DiffResult = Vec<(PathBuf, Option<SHA1>, Option<SHA1>)>;

orion-server/bellatrix/src/orion_client/mod.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
1-
use serde::Serialize;
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
4+
pub enum Status<Path: Clone> {
5+
Modified(Path),
6+
Added(Path),
7+
Removed(Path),
8+
}
9+
10+
#[derive(Clone, Debug, Hash, PartialEq, Eq, Deserialize, Serialize)]
11+
pub struct ProjectRelativePath(String);
12+
13+
impl ProjectRelativePath {
14+
pub fn new(path: &str) -> Self {
15+
Self(path.to_owned())
16+
}
17+
18+
pub fn from_abs(abs_path: &str, base: &str) -> Option<Self> {
19+
let opt = abs_path
20+
.strip_prefix(base)
21+
.map(|s| s.trim_start_matches("/"));
22+
opt.map(|s| Self(s.to_owned()))
23+
}
24+
}
25+
26+
impl<Path: Clone> Status<Path> {
27+
pub fn path(&self) -> Path {
28+
match self {
29+
Self::Added(p) => p.clone(),
30+
Self::Modified(p) => p.clone(),
31+
Self::Removed(p) => p.clone(),
32+
}
33+
}
34+
}
235

336
#[derive(Serialize, Debug)]
437
pub struct BuildInfo {
538
pub buck_hash: String,
639
pub buckconfig_hash: String,
740
pub args: Option<Vec<String>>,
41+
pub changes: Vec<Status<ProjectRelativePath>>,
842
}
943

1044
#[derive(Serialize, Debug)]

orion-server/src/api.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,6 @@ pub async fn task_handler(
334334
State(state): State<AppState>,
335335
Json(req): Json<TaskRequest>,
336336
) -> impl IntoResponse {
337-
// for now we do not extract from file, just use the fixed build target.
338-
let target = "//...".to_string();
339-
340337
// create task id
341338
let task_id = Uuid::now_v7();
342339

@@ -374,7 +371,7 @@ pub async fn task_handler(
374371
&req.repo,
375372
req.cl,
376373
build.clone(),
377-
target.clone(),
374+
String::new(),
378375
)
379376
.await;
380377
results.push(result);
@@ -386,7 +383,6 @@ pub async fn task_handler(
386383
task_id,
387384
&req.cl_link,
388385
build.clone(),
389-
target.clone(),
390386
req.repo.clone(),
391387
req.cl,
392388
)
@@ -426,6 +422,9 @@ pub async fn task_handler(
426422
}
427423

428424
/// Handle immediate task dispatch logic (original task_handler logic)
425+
///
426+
/// # Note
427+
/// The `target` field is deprecated, only remain for compatibility reasons.
429428
async fn handle_immediate_task_dispatch(
430429
state: AppState,
431430
task_id: Uuid,
@@ -476,8 +475,8 @@ async fn handle_immediate_task_dispatch(
476475
// Create build information structure
477476
let build_info = BuildInfo {
478477
repo: repo.to_string(),
479-
target: target.clone(),
480478
args: req.args.clone(),
479+
changes: req.changes.clone(),
481480
start_at: chrono::Utc::now(),
482481
cl: cl.to_string(),
483482
_worker_id: chosen_id.clone(),
@@ -508,7 +507,7 @@ async fn handle_immediate_task_dispatch(
508507
let msg: WSMessage = WSMessage::Task {
509508
id: build_id.to_string(),
510509
repo: repo.to_string(),
511-
target,
510+
changes: req.changes.clone(),
512511
args: req.args.clone(),
513512
cl_link: cl_link.to_string(),
514513
};

orion-server/src/scheduler.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::model::builds;
22
use chrono::FixedOffset;
33
use dashmap::DashMap;
4+
use orion::repo::sapling::status::{ProjectRelativePath, Status};
45
use orion::ws::WSMessage;
56
use rand::Rng;
67
use sea_orm::ActiveModelTrait;
@@ -23,6 +24,7 @@ pub struct BuildRequest {
2324
pub buck_hash: String,
2425
pub buckconfig_hash: String,
2526
pub args: Option<Vec<String>>,
27+
pub changes: Vec<Status<ProjectRelativePath>>,
2628
}
2729

2830
/// Pending task waiting for dispatch
@@ -34,7 +36,6 @@ pub struct PendingTask {
3436
pub repo: String,
3537
pub cl: i64,
3638
pub request: BuildRequest,
37-
pub target: String,
3839
pub created_at: Instant,
3940
}
4041

@@ -134,9 +135,9 @@ pub struct TaskQueueStats {
134135
#[allow(dead_code)]
135136
pub struct BuildInfo {
136137
pub repo: String,
137-
pub target: String,
138138
pub args: Option<Vec<String>>,
139139
pub start_at: DateTimeUtc,
140+
pub changes: Vec<Status<ProjectRelativePath>>,
140141
pub cl: String,
141142
pub _worker_id: String,
142143
pub log_file: Arc<Mutex<std::fs::File>>,
@@ -241,7 +242,6 @@ impl TaskScheduler {
241242
task_id: Uuid,
242243
cl_link: &str,
243244
request: BuildRequest,
244-
target: String,
245245
repo: String,
246246
cl: i64,
247247
) -> Result<Uuid, String> {
@@ -252,7 +252,6 @@ impl TaskScheduler {
252252
cl_link: cl_link.to_string(),
253253
build_id,
254254
request,
255-
target,
256255
created_at: Instant::now(),
257256
repo,
258257
cl,
@@ -372,9 +371,9 @@ impl TaskScheduler {
372371
// Create build information
373372
let build_info = BuildInfo {
374373
repo: pending_task.repo.clone(),
375-
target: pending_task.target.clone(),
376374
args: pending_task.request.args.clone(),
377375
start_at: chrono::Utc::now(),
376+
changes: pending_task.request.changes.clone(),
378377
cl: pending_task.cl.to_string(),
379378
_worker_id: chosen_id.clone(),
380379
log_file,
@@ -406,9 +405,9 @@ impl TaskScheduler {
406405
let msg = WSMessage::Task {
407406
id: pending_task.build_id.to_string(),
408407
repo: pending_task.repo,
409-
target: pending_task.target,
410408
args: pending_task.request.args,
411409
cl_link: pending_task.cl_link.to_string(),
410+
changes: pending_task.request.changes.clone(),
412411
};
413412

414413
// Send task to worker
@@ -659,8 +658,8 @@ mod tests {
659658
buck_hash: "hash1".to_string(),
660659
buckconfig_hash: "config1".to_string(),
661660
args: None,
661+
changes: vec![],
662662
},
663-
target: "target1".to_string(),
664663
created_at: Instant::now(),
665664
repo: "/test/repo".to_string(),
666665
cl: 123456,
@@ -674,8 +673,8 @@ mod tests {
674673
buck_hash: "hash2".to_string(),
675674
buckconfig_hash: "config2".to_string(),
676675
args: None,
676+
changes: vec![],
677677
},
678-
target: "target2".to_string(),
679678
created_at: Instant::now(),
680679
repo: "/test2/repo".to_string(),
681680
cl: 123457,
@@ -712,8 +711,8 @@ mod tests {
712711
buck_hash: "hash".to_string(),
713712
buckconfig_hash: "config".to_string(),
714713
args: None,
714+
changes: vec![],
715715
},
716-
target: "target".to_string(),
717716
created_at: Instant::now(),
718717
repo: "/test/repo".to_string(),
719718
cl: 123456,

orion/Cargo.toml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@ axum = { workspace = true, features = ["macros"] }
88
tokio = { workspace = true, features = ["rt-multi-thread", "fs", "process"] }
99
tracing = { workspace = true }
1010
tracing-subscriber = { workspace = true }
11-
serde = { workspace = true, features = ["derive"] }
12-
uuid = { workspace = true, features = ["v7"] }
11+
serde = { workspace = true, features = ["derive", "rc"] }
1312
futures-util = { workspace = true }
14-
dashmap = { workspace = true }
1513
once_cell = { workspace = true }
1614
dotenvy = { workspace = true }
1715
tokio-tungstenite = { workspace = true , features = ["native-tls"]}
1816
tungstenite = { workspace = true }
1917
serde_json = { workspace = true }
2018
reqwest = { workspace = true, features = ["json", "rustls-tls"] }
19+
uuid = { workspace = true, features = ["v4"] }
20+
anyhow = "1.0"
21+
itertools = "0.13.0"
22+
argfile = "0.1.5"
23+
clap = {version = "4.1.4"}
24+
equivalent = "1.0.0"
25+
futures = "0.3.30"
26+
parse-display = "0.8.2"
27+
rayon = "1.6.1"
28+
tempfile = "3.1.0"
29+
audit = { path = "./audit" }
30+
td_util = { path = "./td_util" }
31+
td_util_buck = { path = "./buck" }
32+
thiserror = "1.0.36"
33+
utoipa-axum.workspace = true
34+
utoipa.workspace = true
35+
utoipa-swagger-ui = { workspace = true, features = ["axum"] }

0 commit comments

Comments
 (0)