Implement reading from cookbook lock

This commit is contained in:
Wildan M 2026-05-06 01:06:53 +07:00
parent a7a7a606c3
commit 16c8c87d4f
No known key found for this signature in database
GPG Key ID: 01AC53185C679C79
2 changed files with 75 additions and 5 deletions

View File

@ -8,7 +8,9 @@ use cookbook::cook::pty::{PtyOut, UnixSlavePty, flush_pty, setup_pty, write_to_p
use cookbook::cook::script::KILL_ALL_PID;
use cookbook::cook::tree::{self, WalkTreeEntry};
use cookbook::cook::{fetch_repo, ident};
use cookbook::recipe::{CookRecipe, recipes_flatten_package_names, recipes_mark_as_deps};
use cookbook::recipe::{
CookRecipe, SourceRecipe, recipes_flatten_package_names, recipes_mark_as_deps,
};
use cookbook::{Error, Result, staged_pkg};
use pkg::{PackageName, PackageState};
use ratatui::Terminal;
@ -679,6 +681,31 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
}
};
if !get_config().recipe_lock.is_empty() {
let lock = &get_config().recipe_lock;
for recipe in recipes.iter_mut() {
if let Some(lock_recipe) = lock.get(recipe.name.as_str()) {
if let Some(rule) = &lock_recipe.fsrule {
recipe.rule = rule.into();
recipe.reload_recipe()?;
}
if let Some(gitrev) = &lock_recipe.gitrev {
if let Some(SourceRecipe::Git { rev, branch, .. }) = &mut recipe.recipe.source {
*rev = Some(gitrev.clone());
*branch = None;
} else {
println!(
"DEBUG: Recipe {:?} contains into git rev but recipe source is not git",
recipe.name.as_str()
);
}
recipe.rule = "source".into();
recipe.reload_recipe()?;
}
}
}
}
if command.is_building() && recipes.iter().any(|r| r.rule == "binary") {
let (_, repository) = fetch_repo::get_binary_repo();
for recipe in recipes.iter_mut() {

View File

@ -1,8 +1,13 @@
use std::{collections::HashMap, env, fs, str::FromStr, sync::OnceLock};
use std::{
collections::{BTreeMap, HashMap},
env, fs,
str::FromStr,
sync::OnceLock,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)]
#[derive(Debug, Default, Clone, Deserialize, PartialEq)]
#[serde(default)]
pub struct CookConfigOpt {
/// whether to run offline
@ -34,7 +39,7 @@ pub struct CookConfigOpt {
pub write_filetree: Option<bool>,
}
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)]
#[derive(Debug, Default, Clone, PartialEq)]
pub struct CookConfig {
pub offline: bool,
pub jobs: usize,
@ -67,7 +72,31 @@ impl From<CookConfigOpt> for CookConfig {
}
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)]
#[serde(default)]
pub struct CookLockOpt {
pub recipes: BTreeMap<String, RecipeLock>,
}
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)]
#[serde(default)]
pub struct RecipeLock {
pub fsrule: Option<String>,
pub gitrev: Option<String>,
}
const COOKBOOK_LOCK_HEADER: &str = r#"This file is generated automatically.
All configuration here overrides anything from recipes or config directory.
"#;
impl CookLockOpt {
pub fn save(&self) {
let str = toml::to_string(&self).unwrap();
fs::write("cookbook.lock", format!("{COOKBOOK_LOCK_HEADER}\n{str}")).unwrap();
}
}
#[derive(Debug, Default, Deserialize, PartialEq)]
#[serde(default)]
pub struct CookbookConfig {
#[serde(rename = "cook")]
@ -75,6 +104,7 @@ pub struct CookbookConfig {
#[serde(skip)]
pub cook: CookConfig,
pub mirrors: HashMap<String, String>,
pub recipe_lock: BTreeMap<String, RecipeLock>,
}
static CONFIG: OnceLock<CookbookConfig> = OnceLock::new();
@ -145,6 +175,19 @@ pub fn init_config() {
config.cook = CookConfig::from(config.cook_opt.clone());
let lock: CookLockOpt = if fs::exists("cookbook.lock").unwrap_or(false) {
let toml_content = fs::read_to_string("cookbook.lock")
.map_err(|e| format!("Unable to read lock: {:?}", e))
.unwrap();
toml::from_str(&toml_content)
.map_err(|e| format!("Unable to parse lock (plz delete manually): {:?}", e))
.unwrap()
} else {
CookLockOpt::default()
};
config.recipe_lock = lock.recipes;
CONFIG.set(config).expect("config is initialized twice");
}