Implement change-rule command

This commit is contained in:
Wildan M 2026-05-06 02:35:17 +07:00
parent 16c8c87d4f
commit 8d6ae193e7
No known key found for this signature in database
GPG Key ID: 01AC53185C679C79
4 changed files with 115 additions and 8 deletions

1
.gitignore vendored
View File

@ -14,6 +14,7 @@
/repo /repo
/web /web
/cookbook.toml /cookbook.toml
/cookbook.lock
source source
source.tmp source.tmp
source-new source-new

View File

@ -260,6 +260,40 @@ ucri.%: $(FSTOOLS_TAG) FORCE
$(MAKE) i.$* $(MAKE) i.$*
endif endif
# Set recipe rule to "binary" then invoke clean
bc.%: $(FSTOOLS_TAG) FORCE
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
$(REPO_BIN) change-rule --set-rule=binary $(foreach f,$(subst $(comma), ,$*),$(f))
endif
# Set recipe rule to "source" then invoke clean
sc.%: $(FSTOOLS_TAG) FORCE
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
$(REPO_BIN) change-rule --set-rule=source $(foreach f,$(subst $(comma), ,$*),$(f))
endif
# Reset recipe rule then invoke clean
cc.%: $(FSTOOLS_TAG) FORCE
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
$(REPO_BIN) change-rule --set-rule= $(foreach f,$(subst $(comma), ,$*),$(f))
endif
# Set recipe rule to "binary" then invoke clean and rebuild
bcr.%: $(FSTOOLS_TAG) FORCE
$(MAKE) bc.$*
$(MAKE) r.$*
# Set recipe rule to "source" then invoke clean and rebuild
scr.%: $(FSTOOLS_TAG) FORCE
$(MAKE) sc.$*
$(MAKE) r.$*
export DEBUG_BIN?= export DEBUG_BIN?=
# Debug a statically linked program with gdbgui, for example: debug.drivers-initfs DEBUG_BIN=pcid # Debug a statically linked program with gdbgui, for example: debug.drivers-initfs DEBUG_BIN=pcid

View File

@ -1,5 +1,5 @@
use ansi_to_tui::IntoText; use ansi_to_tui::IntoText;
use cookbook::config::{CookConfig, get_config, init_config}; use cookbook::config::{CookConfig, CookLockOpt, get_config, init_config};
use cookbook::cook::cook_build::{build, get_stage_dirs, remove_stage_dir}; use cookbook::cook::cook_build::{build, get_stage_dirs, remove_stage_dir};
use cookbook::cook::fetch::{FetchResult, fetch, fetch_offline}; use cookbook::cook::fetch::{FetchResult, fetch, fetch_offline};
use cookbook::cook::fs::{create_dir, create_target_dir, remove_all, run_command}; use cookbook::cook::fs::{create_dir, create_target_dir, remove_all, run_command};
@ -52,7 +52,9 @@ const REPO_HELP_STR: &str = r#"
find find path of recipe packages find find path of recipe packages
cook-tree show tree of recipe build cook-tree show tree of recipe build
push-tree show tree of recipe packages push-tree show tree of recipe packages
capture-rev write lock to git recipes
change-rule override rule to recipes
common flags: common flags:
--cookbook=<cookbook_dir> the "recipes" folder, default to $PWD/recipes --cookbook=<cookbook_dir> the "recipes" folder, default to $PWD/recipes
--repo=<repo_dir> the "repo" folder, default to $PWD/repo --repo=<repo_dir> the "repo" folder, default to $PWD/repo
@ -63,6 +65,8 @@ const REPO_HELP_STR: &str = r#"
--category=<category> apply to all recipes in <cookbook_dir>/<category> --category=<category> apply to all recipes in <cookbook_dir>/<category>
--filesystem=<filesystem> override recipes config using installer file --filesystem=<filesystem> override recipes config using installer file
--repo-binary override recipes config to use repo_binary --repo-binary override recipes config to use repo_binary
--set-rule=<rule> used in "change-rule", set wanted config rule
--rollback=<rev> used in "capture-rev", rollback to a commit instead
cook env and their defaults: cook env and their defaults:
CI= set to any value to disable TUI CI= set to any value to disable TUI
@ -87,6 +91,8 @@ struct CliConfig {
logs_dir: Option<PathBuf>, logs_dir: Option<PathBuf>,
category: Option<PathBuf>, category: Option<PathBuf>,
filesystem: Option<redox_installer::Config>, filesystem: Option<redox_installer::Config>,
rollback: Option<String>,
set_rule: Option<String>,
with_package_deps: bool, with_package_deps: bool,
all: bool, all: bool,
cook: CookConfig, cook: CookConfig,
@ -103,6 +109,8 @@ enum CliCommand {
Push, Push,
PushTree, PushTree,
Find, Find,
CaptureRev,
ChangeRule,
} }
impl CliCommand { impl CliCommand {
@ -110,7 +118,11 @@ impl CliCommand {
*self == CliCommand::PushTree || *self == CliCommand::CookTree || *self == CliCommand::Find *self == CliCommand::PushTree || *self == CliCommand::CookTree || *self == CliCommand::Find
} }
pub fn is_building(&self) -> bool { pub fn is_building(&self) -> bool {
*self == CliCommand::Fetch || *self == CliCommand::Cook || *self == CliCommand::CookTree *self == CliCommand::Fetch
|| *self == CliCommand::Cook
|| *self == CliCommand::CookTree
|| *self == CliCommand::CaptureRev
|| *self == CliCommand::ChangeRule
} }
pub fn is_pushing(&self) -> bool { pub fn is_pushing(&self) -> bool {
*self == CliCommand::Push || *self == CliCommand::PushTree *self == CliCommand::Push || *self == CliCommand::PushTree
@ -136,6 +148,8 @@ impl FromStr for CliCommand {
"push-tree" => Ok(CliCommand::PushTree), "push-tree" => Ok(CliCommand::PushTree),
"cook-tree" => Ok(CliCommand::CookTree), "cook-tree" => Ok(CliCommand::CookTree),
"find" => Ok(CliCommand::Find), "find" => Ok(CliCommand::Find),
"capture-rev" => Ok(CliCommand::CaptureRev),
"change-rule" => Ok(CliCommand::ChangeRule),
_ => bail_options_err!("Unknown command {:?}", s), _ => bail_options_err!("Unknown command {:?}", s),
} }
} }
@ -153,6 +167,8 @@ impl ToString for CliCommand {
CliCommand::PushTree => "push-tree".to_string(), CliCommand::PushTree => "push-tree".to_string(),
CliCommand::CookTree => "cook-tree".to_string(), CliCommand::CookTree => "cook-tree".to_string(),
CliCommand::Find => "find".to_string(), CliCommand::Find => "find".to_string(),
CliCommand::CaptureRev => "capture-rev".to_string(),
CliCommand::ChangeRule => "change-rule".to_string(),
} }
} }
} }
@ -180,6 +196,8 @@ impl CliConfig {
cook: get_config().cook.clone(), cook: get_config().cook.clone(),
all: false, all: false,
filesystem: None, filesystem: None,
rollback: None,
set_rule: None,
}) })
} }
} }
@ -244,6 +262,12 @@ fn main_inner() -> Result<()> {
if command == CliCommand::Push { if command == CliCommand::Push {
return handle_push(&recipes, &config); return handle_push(&recipes, &config);
} }
if command == CliCommand::ChangeRule {
return handle_change_rule(&recipes, &config);
}
if command == CliCommand::CaptureRev {
return handle_capture_rev(&recipes, &config);
}
let verbose = config.cook.verbose; let verbose = config.cook.verbose;
for recipe in &recipes { for recipe in &recipes {
@ -388,13 +412,11 @@ fn repo_inner(config: &CliConfig, command: &CliCommand, recipe: &CookRecipe) ->
CliCommand::Unfetch | CliCommand::Clean | CliCommand::CleanTarget => { CliCommand::Unfetch | CliCommand::Clean | CliCommand::CleanTarget => {
handle_clean(recipe, config, command)? handle_clean(recipe, config, command)?
} }
CliCommand::Push => unreachable!(),
CliCommand::PushTree => unreachable!(),
CliCommand::CookTree => unreachable!(),
CliCommand::Find => { CliCommand::Find => {
println!("{}", recipe.dir.display()); println!("{}", recipe.dir.display());
false false
} }
_ => unreachable!(),
}) })
} }
@ -431,6 +453,8 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
"--repo" => config.repo_dir = PathBuf::from(value), "--repo" => config.repo_dir = PathBuf::from(value),
"--sysroot" => config.sysroot_dir = PathBuf::from(value), "--sysroot" => config.sysroot_dir = PathBuf::from(value),
"--category" => config.category = Some(PathBuf::from(value)), "--category" => config.category = Some(PathBuf::from(value)),
"--set-rule" => config.set_rule = Some(value.into()),
"--rollback" => config.rollback = Some(value.into()),
"--filesystem" => { "--filesystem" => {
config.filesystem = Some({ config.filesystem = Some({
let r = redox_installer::Config::from_file(&PathBuf::from(value)); let r = redox_installer::Config::from_file(&PathBuf::from(value));
@ -944,6 +968,48 @@ fn handle_tree(recipes: &Vec<CookRecipe>, is_build_tree: bool, _config: &CliConf
Ok(()) Ok(())
} }
fn handle_change_rule(recipes: &Vec<CookRecipe>, config: &CliConfig) -> Result<()> {
let mut lock = get_config().recipe_lock.clone();
let is_pruning = config.set_rule.as_ref().is_some_and(|s| s.is_empty());
for recipe in recipes {
let mut recipe_lock = lock.get(recipe.name.as_str()).cloned().unwrap_or_default();
let cached = if is_pruning {
recipe_lock.fsrule.take().is_none()
} else {
let new_rule = config
.set_rule
.as_ref()
.cloned()
.unwrap_or_else(|| recipe.rule.clone());
let old_rule = recipe_lock.fsrule.replace(new_rule.clone());
old_rule == Some(new_rule)
};
if recipe_lock.is_empty() {
lock.remove(recipe.name.as_str());
} else {
lock.insert(recipe.name.to_string(), recipe_lock);
}
let clean_cached = if !cached {
handle_clean(recipe, config, &CliCommand::Clean)?
} else {
true
};
if cached && clean_cached {
print_cached(&CliCommand::ChangeRule, &recipe.name);
} else {
print_success(&CliCommand::ChangeRule, &recipe.name);
}
}
CookLockOpt { recipes: lock }.save();
Ok(())
}
fn handle_capture_rev(_recipes: &Vec<CookRecipe>, _config: &CliConfig) -> Result<()> {
todo!()
}
// //
// ------------- TUI SPECIFIC CODE ------------------- // ------------- TUI SPECIFIC CODE -------------------
// //

View File

@ -85,8 +85,14 @@ pub struct RecipeLock {
pub gitrev: Option<String>, pub gitrev: Option<String>,
} }
const COOKBOOK_LOCK_HEADER: &str = r#"This file is generated automatically. impl RecipeLock {
All configuration here overrides anything from recipes or config directory. pub fn is_empty(&self) -> bool {
self.fsrule.is_none() && self.gitrev.is_none()
}
}
const COOKBOOK_LOCK_HEADER: &str = r#"# This file is generated automatically.
# All configuration here overrides anything from recipes or config directory.
"#; "#;
impl CookLockOpt { impl CookLockOpt {