refactor(baker/bake): move relating part into separate directory

This commit is contained in:
Catty Steve
2026-03-31 13:16:14 +08:00
parent 3e8b256889
commit 20919d53ad
9 changed files with 23 additions and 175 deletions
View File
+20 -16
View File
@@ -3,7 +3,7 @@ pub mod env;
pub mod security;
pub mod stage;
use crate::cli::Cli;
use crate::{cli::Cli, error::PrebakeError};
pub use config::PrebakeConfig;
pub use security::prebake_drop_privilege;
@@ -24,7 +24,7 @@ pub async fn prebake(config_path: &str, cli: &Cli) -> anyhow::Result<()> {
for error in errors {
log::error!("Error: {}", error);
}
// TODO: Raise an error
anyhow::bail!(PrebakeError::ValidateError());
}
let mut ctx = crate::ExecutionContext {
@@ -38,8 +38,7 @@ pub async fn prebake(config_path: &str, cli: &Cli) -> anyhow::Result<()> {
// Bootstrap stage
ctx.task_id = format!("{}-{}-bootstrap", cli.pipeline, cli.build_id);
// TODO: Pass real event_tx
let result = stage::bootstrap::bootstrap(&config, &ctx, &None).await;
result?;
stage::bootstrap::bootstrap(&config, &ctx, &None).await?;
// TODO: Early security implementation
// EarlyHook stage
@@ -48,15 +47,21 @@ pub async fn prebake(config_path: &str, cli: &Cli) -> anyhow::Result<()> {
Some(hooks) => hooks.early.clone(),
None => None,
};
let result = stage::hook::hook(earlyhook, &ctx, None).await;
result?;
stage::hook::hook(earlyhook, &ctx, None).await?;
// DepsSystem stage
ctx.task_id = format!("{}-{}-depssystem", cli.pipeline, cli.build_id);
// TODO: Dependency stage
// DepsUser stage
ctx.task_id = format!("{}-{}-depsuser", cli.pipeline, cli.build_id);
// TODO: Dependency stage
if let Some(dependencies) = config.dependencies {
// DepsSystem stage
ctx.task_id = format!("{}-{}-depssystem", cli.pipeline, cli.build_id);
if let Some(system) = dependencies.system {
stage::depssystem::depssystem(&system, &ctx, None).await?;
}
// DepsUser stage
ctx.task_id = format!("{}-{}-depsuser", cli.pipeline, cli.build_id);
if let Some(user) = dependencies.user {
stage::depsuser::depsuser(&user, &ctx, None).await?;
}
}
// LateHook stage
ctx.task_id = format!("{}-{}-latehook", cli.pipeline, cli.build_id);
@@ -64,13 +69,12 @@ pub async fn prebake(config_path: &str, cli: &Cli) -> anyhow::Result<()> {
Some(hooks) => hooks.late.clone(),
None => None,
};
let result = stage::hook::hook(latehook, &ctx, None).await;
result?;
stage::hook::hook(latehook, &ctx, None).await?;
// Ready stage
ctx.task_id = format!("{}-{}-ready", cli.pipeline, cli.build_id);
// TODO: Security stage
// TODO: Ready here!
todo!();
log::info!("Prebake done!");
Ok(())
}
@@ -15,7 +15,7 @@ use std::collections::HashMap;
pub async fn depssystem(
config: &HashMap<String, SystemDependency>,
ctx: &ExecutionContext,
event_tx: &EventSender,
event_tx: EventSender,
) -> Result<(), DependencyError> {
let osinfo = os_info::get();
let engine = Engine::new();
+2 -2
View File
@@ -8,7 +8,7 @@ use std::collections::HashMap;
pub async fn depsuser(
config: &HashMap<String, Value>,
ctx: &ExecutionContext,
event_tx: &EventSender,
event_tx: EventSender,
) -> Result<(), DependencyError> {
for (name, cfg) in config {
let package_manager = match upm::select(name){
@@ -20,7 +20,7 @@ pub async fn depsuser(
};
log::info!("Running user package manager: {}", name);
package_manager.main(cfg, ctx, event_tx).await?;
package_manager.main(cfg, ctx, &event_tx).await?;
}
Ok(())
}
-156
View File
@@ -1,156 +0,0 @@
use regex::Regex;
use std::collections::HashSet;
pub struct Variable {
pub name: String,
pub value: String,
}
lazy_static::lazy_static! {
static ref VAR_REGEX: Regex = Regex::new(r#"\$(?:\{(?:#)?([a-zA-Z_][a-zA-Z0-9_]*)(?:\[(?:\d+|@|\*)?\])?(?:\s*:\s*[+-]?\d+(?::[+-]?\d+)?)?\}|\b([a-zA-Z_][a-zA-Z0-9_]*)\b)"#)
.expect("Failed to compile variable regex");
}
pub fn extract_variables(body: String) -> Vec<Variable> {
let mut variables = HashSet::<String>::new();
let mut variable_list = Vec::<Variable>::new();
for captures in VAR_REGEX.captures_iter(&body) {
if let Some(name) = captures.get(1) {
dbg!(name);
variables.insert(name.as_str().to_string());
} else if let Some(name) = captures.get(2) {
dbg!(name);
variables.insert(name.as_str().to_string());
}
}
for variable in variables {
let variable_element = Variable {
name: variable.clone(),
value: Default::default(), // TODO: 换成workshop-agent通信
};
variable_list.push(variable_element);
}
variable_list
}
// 单元测试模块
#[cfg(test)]
mod tests {
use super::*;
use std::collections::BTreeSet;
/// 辅助函数:将Variable列表转换为排序后的字符串集合(解决HashSet无序问题)
fn sorted_var_names(vars: &[Variable]) -> BTreeSet<String> {
vars.iter().map(|v| v.name.clone()).collect::<BTreeSet<_>>()
}
/// 测试1:基础场景(重复变量去重 + 多种合法格式)
#[test]
fn test_extract_duplicate_variables() {
let script = r#"
echo $var
echo ${var}
echo ${#var}
echo ${var:3:5}
echo ${var: -3}
echo ${var[0]}
echo ${var[@]}
echo ${var[*]}
echo $_var123
echo ${_var123: -5:10}
"#;
let variables = extract_variables(script.to_string());
let sorted_names = sorted_var_names(&variables);
// 预期结果:去重后仅保留var和_var123
let expected = BTreeSet::from(["var".to_string(), "_var123".to_string()]);
assert_eq!(sorted_names, expected);
}
/// 测试2:非法变量(数字开头、特殊字符、$1/$?等)
#[test]
fn test_extract_illegal_variables() {
let script = r#"
echo $1 # 数字开头,不匹配
echo $? # 特殊符号,不匹配
echo $@ # 特殊符号,不匹配
echo ${123var} # 数字开头,不匹配
echo ${var-with-dash} # 含非法字符,不匹配
echo ${var+123} # 含非法字符,不匹配
echo ${} # 空变量,不匹配
echo $ # 无变量名,不匹配
"#;
let variables = extract_variables(script.to_string());
assert!(variables.is_empty());
}
/// 测试3:空输入
#[test]
fn test_extract_empty_body() {
let variables = extract_variables("".to_string());
assert!(variables.is_empty());
}
/// 测试4:无合法变量的输入
#[test]
fn test_extract_no_valid_variables() {
let script = r#"
echo "hello world"
cd /tmp
ls -l
echo $123abc # 数字开头,不匹配
"#;
let variables = extract_variables(script.to_string());
assert!(variables.is_empty());
}
/// 测试5:混合合法/非法变量(仅保留合法项)
#[test]
fn test_extract_mixed_variables() {
let script = r#"
echo $APP_NAME
echo ${DEPLOY_ENV}
echo ${#PORT}
echo $1 # 非法
echo ${invalid-var} # 非法
echo ${_DB_PASSWORD: 5}
echo $? # 非法
"#;
let variables = extract_variables(script.to_string());
let sorted_names = sorted_var_names(&variables);
let expected = BTreeSet::from([
"APP_NAME".to_string(),
"DEPLOY_ENV".to_string(),
"PORT".to_string(),
"_DB_PASSWORD".to_string(),
]);
assert_eq!(sorted_names, expected);
}
/// 测试6:变量名包含数字(合法场景)
#[test]
fn test_extract_var_with_numbers() {
let script = r#"
echo $var123
echo ${var_456}
echo ${#var789: 10}
"#;
let variables = extract_variables(script.to_string());
let sorted_names = sorted_var_names(&variables);
let expected = BTreeSet::from([
"var123".to_string(),
"var_456".to_string(),
"var789".to_string(),
]);
assert_eq!(sorted_names, expected);
}
}