mirror of
https://gitlab.redox-os.org/redox-os/redox.git
synced 2026-06-24 05:44:17 +08:00
Merge branch 'tree-smarter' into 'master'
Accurate push with deps, separate tree command See merge request redox-os/redox!1879
This commit is contained in:
commit
58b6a7e45f
36
mk/repo.mk
36
mk/repo.mk
@ -13,12 +13,20 @@ endif
|
||||
|
||||
comma := ,
|
||||
|
||||
# List all recipes in a tree fashion specified by the filesystem config
|
||||
tree: $(FSTOOLS_TAG) $(CONTAINER_TAG)
|
||||
# List all recipes in a cook-tree fashion specified by the filesystem config
|
||||
repo-tree: $(FSTOOLS_TAG) $(CONTAINER_TAG)
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
@./target/release/repo tree $(COOKBOOK_OPTS) --with-package-deps
|
||||
@./target/release/repo cook-tree $(COOKBOOK_OPTS) --with-package-deps
|
||||
endif
|
||||
|
||||
# List all recipes in a push-tree fashion specified by the filesystem config
|
||||
image-tree: $(FSTOOLS_TAG) $(CONTAINER_TAG)
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
@./target/release/repo push-tree $(COOKBOOK_OPTS) --with-package-deps
|
||||
endif
|
||||
|
||||
# Fetch all recipes source or binary from filesystem config
|
||||
@ -67,7 +75,7 @@ else
|
||||
./target/release/repo fetch $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
# Invoke repo.sh for one or more targets separated by comma
|
||||
# Invoke cook for one or more targets separated by comma
|
||||
r.%: prefix $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
@ -77,6 +85,14 @@ else
|
||||
./target/release/repo cook $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
# Show what to cook
|
||||
rt.%: prefix $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
./target/release/repo cook-tree $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
MOUNTED_TAG=$(MOUNT_DIR)~
|
||||
|
||||
# Push compiled package into existing image
|
||||
@ -105,6 +121,18 @@ endif
|
||||
pp.%: $(FSTOOLS_TAG) FORCE
|
||||
$(MAKE) p.$*,--with-package-deps
|
||||
|
||||
# Show what to push
|
||||
pt.%: prefix $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
./target/release/repo push-tree $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
# Show what to push (with deps)
|
||||
ppt.%: prefix $(FSTOOLS_TAG) FORCE
|
||||
$(MAKE) pt.$*,--with-package-deps
|
||||
|
||||
# Push all recipes specified by the filesystem config
|
||||
push: $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(ALLOW_FSTOOLS),1)
|
||||
|
||||
115
src/bin/repo.rs
115
src/bin/repo.rs
@ -48,7 +48,8 @@ const REPO_HELP_STR: &str = r#"
|
||||
clean delete recipe artifacts
|
||||
push extract package into sysroot
|
||||
find find path of recipe packages
|
||||
tree show tree of recipe packages
|
||||
cook-tree show tree of recipe build
|
||||
push-tree show tree of recipe packages
|
||||
|
||||
common flags:
|
||||
--cookbook=<cookbook_dir> the "recipes" folder, default to $PWD/recipes
|
||||
@ -90,22 +91,23 @@ struct CliConfig {
|
||||
enum CliCommand {
|
||||
Fetch,
|
||||
Cook,
|
||||
CookTree,
|
||||
Unfetch,
|
||||
Clean,
|
||||
Push,
|
||||
Tree,
|
||||
PushTree,
|
||||
Find,
|
||||
}
|
||||
|
||||
impl CliCommand {
|
||||
pub fn is_informational(&self) -> bool {
|
||||
*self == CliCommand::Tree || *self == CliCommand::Find
|
||||
*self == CliCommand::PushTree || *self == CliCommand::CookTree || *self == CliCommand::Find
|
||||
}
|
||||
pub fn is_building(&self) -> bool {
|
||||
*self == CliCommand::Fetch || *self == CliCommand::Cook
|
||||
*self == CliCommand::Fetch || *self == CliCommand::Cook || *self == CliCommand::CookTree
|
||||
}
|
||||
pub fn is_pushing(&self) -> bool {
|
||||
*self == CliCommand::Push || *self == CliCommand::Tree
|
||||
*self == CliCommand::Push || *self == CliCommand::PushTree
|
||||
}
|
||||
pub fn is_cleaning(&self) -> bool {
|
||||
*self == CliCommand::Clean || *self == CliCommand::Unfetch
|
||||
@ -122,7 +124,8 @@ impl FromStr for CliCommand {
|
||||
"unfetch" => Ok(CliCommand::Unfetch),
|
||||
"clean" => Ok(CliCommand::Clean),
|
||||
"push" => Ok(CliCommand::Push),
|
||||
"tree" => Ok(CliCommand::Tree),
|
||||
"push-tree" => Ok(CliCommand::PushTree),
|
||||
"cook-tree" => Ok(CliCommand::CookTree),
|
||||
"find" => Ok(CliCommand::Find),
|
||||
_ => Err(anyhow!("Unknown command '{}'\n{}\n", s, REPO_HELP_STR)),
|
||||
}
|
||||
@ -137,7 +140,8 @@ impl ToString for CliCommand {
|
||||
CliCommand::Unfetch => "unfetch".to_string(),
|
||||
CliCommand::Clean => "clean".to_string(),
|
||||
CliCommand::Push => "push".to_string(),
|
||||
CliCommand::Tree => "tree".to_string(),
|
||||
CliCommand::PushTree => "push-tree".to_string(),
|
||||
CliCommand::CookTree => "cook-tree".to_string(),
|
||||
CliCommand::Find => "find".to_string(),
|
||||
}
|
||||
}
|
||||
@ -186,12 +190,12 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let (config, command, recipe_names) = parse_args(args)?;
|
||||
let (config, command, recipes) = parse_args(args)?;
|
||||
if command.is_building() {
|
||||
ident::init_ident();
|
||||
}
|
||||
if command == CliCommand::Cook && config.cook.tui {
|
||||
if let Some((name, e)) = run_tui_cook(config.clone(), recipe_names.clone())? {
|
||||
if let Some((name, e)) = run_tui_cook(config.clone(), recipes.clone())? {
|
||||
let _ = stderr().write(e.as_bytes());
|
||||
let _ = stderr().write(b"\n\n");
|
||||
print_failed(&command, &name);
|
||||
@ -199,17 +203,20 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
} else {
|
||||
print_success(&command, None);
|
||||
}
|
||||
return publish_packages(&recipe_names, &config.repo_dir);
|
||||
return publish_packages(&recipes, &config.repo_dir);
|
||||
}
|
||||
if command == CliCommand::Tree {
|
||||
return handle_tree(&recipe_names, &config);
|
||||
if command == CliCommand::PushTree {
|
||||
return handle_tree(&recipes, false, &config);
|
||||
}
|
||||
if command == CliCommand::CookTree {
|
||||
return handle_tree(&recipes, true, &config);
|
||||
}
|
||||
if command == CliCommand::Push {
|
||||
return handle_push(&recipe_names, &config);
|
||||
return handle_push(&recipes, &config);
|
||||
}
|
||||
|
||||
let verbose = config.cook.verbose;
|
||||
for recipe in &recipe_names {
|
||||
for recipe in &recipes {
|
||||
match repo_inner(&config, &command, recipe) {
|
||||
Ok(_) => {
|
||||
if !command.is_informational() {
|
||||
@ -234,14 +241,14 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
if command == CliCommand::Cook {
|
||||
return publish_packages(&recipe_names, &config.repo_dir);
|
||||
return publish_packages(&recipes, &config.repo_dir);
|
||||
}
|
||||
|
||||
if verbose && recipe_names.len() > 1 {
|
||||
if verbose && recipes.len() > 1 {
|
||||
println!(
|
||||
"\nCommand '{}' completed for {} recipes.",
|
||||
command.to_string(),
|
||||
recipe_names.len()
|
||||
recipes.len()
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
@ -348,7 +355,8 @@ fn repo_inner(
|
||||
CliCommand::Unfetch => handle_clean(recipe, config, true, true)?,
|
||||
CliCommand::Clean => handle_clean(recipe, config, false, true)?,
|
||||
CliCommand::Push => unreachable!(),
|
||||
CliCommand::Tree => unreachable!(),
|
||||
CliCommand::PushTree => unreachable!(),
|
||||
CliCommand::CookTree => unreachable!(),
|
||||
CliCommand::Find => println!("{}", recipe.dir.display()),
|
||||
})
|
||||
}
|
||||
@ -564,17 +572,21 @@ fn parse_args(args: Vec<String>) -> anyhow::Result<(CliConfig, CliCommand, Vec<C
|
||||
CookRecipe::get_package_deps_recursive(&binary_recipe_names, true)?;
|
||||
}
|
||||
|
||||
let mut recipes = if command.is_building() {
|
||||
CookRecipe::get_build_deps_recursive(&source_recipe_names, true)?
|
||||
} else {
|
||||
CookRecipe::from_list(source_recipe_names.clone())?
|
||||
};
|
||||
let mut recipes =
|
||||
if command.is_building() || (command.is_pushing() && config.with_package_deps) {
|
||||
// Pushing do not need dev deps, so does binary recipes at building
|
||||
let include_dev = command.is_building();
|
||||
CookRecipe::get_build_deps_recursive(&source_recipe_names, include_dev)?
|
||||
} else {
|
||||
CookRecipe::from_list(source_recipe_names.clone())?
|
||||
};
|
||||
|
||||
let binary_recipes = if command.is_building() {
|
||||
CookRecipe::get_build_deps_recursive(&binary_recipe_names, false)?
|
||||
} else {
|
||||
CookRecipe::from_list(binary_recipe_names.clone())?
|
||||
};
|
||||
let binary_recipes =
|
||||
if command.is_building() || (command.is_pushing() && config.with_package_deps) {
|
||||
CookRecipe::get_build_deps_recursive(&binary_recipe_names, false)?
|
||||
} else {
|
||||
CookRecipe::from_list(binary_recipe_names.clone())?
|
||||
};
|
||||
|
||||
let ignore_recipes = CookRecipe::from_list(ignore_recipe_names.clone())?;
|
||||
|
||||
@ -607,8 +619,9 @@ fn parse_args(args: Vec<String>) -> anyhow::Result<(CliConfig, CliCommand, Vec<C
|
||||
if config.with_package_deps {
|
||||
recipe_names = CookRecipe::get_package_deps_recursive(&recipe_names, true)?;
|
||||
}
|
||||
if command.is_building() {
|
||||
CookRecipe::get_build_deps_recursive(&recipe_names, true)?
|
||||
if command.is_building() || (command.is_pushing() && config.with_package_deps) {
|
||||
let include_dev = command.is_building();
|
||||
CookRecipe::get_build_deps_recursive(&recipe_names, include_dev)?
|
||||
} else {
|
||||
CookRecipe::from_list(recipe_names.clone())?
|
||||
}
|
||||
@ -758,6 +771,7 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> anyhow::Result<
|
||||
&recipe_map,
|
||||
"",
|
||||
i == num_roots - 1,
|
||||
false,
|
||||
&mut visited,
|
||||
&mut total_size,
|
||||
handle_push_inner,
|
||||
@ -803,7 +817,11 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> anyhow::Result<
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_tree(recipes: &Vec<CookRecipe>, _config: &CliConfig) -> anyhow::Result<()> {
|
||||
fn handle_tree(
|
||||
recipes: &Vec<CookRecipe>,
|
||||
is_build_tree: bool,
|
||||
_config: &CliConfig,
|
||||
) -> anyhow::Result<()> {
|
||||
let recipe_map: HashMap<&PackageName, &CookRecipe> =
|
||||
recipes.iter().map(|r| (&r.name, r)).collect();
|
||||
let mut total_size: u64 = 0;
|
||||
@ -816,22 +834,37 @@ fn handle_tree(recipes: &Vec<CookRecipe>, _config: &CliConfig) -> anyhow::Result
|
||||
&recipe_map,
|
||||
"",
|
||||
i == num_roots - 1,
|
||||
is_build_tree,
|
||||
&mut visited,
|
||||
&mut total_size,
|
||||
)?;
|
||||
}
|
||||
|
||||
println!("");
|
||||
println!(
|
||||
"Estimated image size: {} of {} {}",
|
||||
tree::format_size(total_size),
|
||||
visited.len(),
|
||||
if visited.len() == 1 {
|
||||
"package"
|
||||
} else {
|
||||
"packages"
|
||||
},
|
||||
);
|
||||
if is_build_tree {
|
||||
println!(
|
||||
"Build summary: {} need build, {} may rebuild, with total of {} {}",
|
||||
total_size,
|
||||
roots.len(),
|
||||
visited.len(),
|
||||
if visited.len() == 1 {
|
||||
"recipe"
|
||||
} else {
|
||||
"recipes"
|
||||
},
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"Estimated image size: {} of {} {}",
|
||||
tree::format_size(total_size),
|
||||
visited.len(),
|
||||
if visited.len() == 1 {
|
||||
"package"
|
||||
} else {
|
||||
"packages"
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ pub fn display_tree_entry(
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
prefix: &str,
|
||||
is_last: bool,
|
||||
is_build_tree: bool,
|
||||
visited: &mut HashSet<PackageName>,
|
||||
total_size: &mut u64,
|
||||
) -> anyhow::Result<()> {
|
||||
@ -29,6 +30,7 @@ pub fn display_tree_entry(
|
||||
recipe_map,
|
||||
prefix,
|
||||
is_last,
|
||||
is_build_tree,
|
||||
visited,
|
||||
total_size,
|
||||
display_pkg_fn,
|
||||
@ -40,6 +42,7 @@ pub fn walk_tree_entry(
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
prefix: &str,
|
||||
is_last: bool,
|
||||
is_build_tree: bool,
|
||||
visited: &mut HashSet<PackageName>,
|
||||
total_size: &mut u64,
|
||||
op: fn(&PackageName, &str, bool, &WalkTreeEntry) -> anyhow::Result<()>,
|
||||
@ -47,7 +50,7 @@ pub fn walk_tree_entry(
|
||||
let cook_recipe = match recipe_map.get(package_name) {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
// TODO: This is a dependency, but it's not in recipe list
|
||||
// Data not provided, will not be processed by the build system
|
||||
op(package_name, prefix, is_last, &WalkTreeEntry::Missing)?;
|
||||
return Ok(());
|
||||
}
|
||||
@ -69,19 +72,28 @@ pub fn walk_tree_entry(
|
||||
}
|
||||
|
||||
visited.insert(package_name.clone());
|
||||
if let WalkTreeEntry::Built(_p, pkg_size) = &entry {
|
||||
*total_size += pkg_size;
|
||||
if is_build_tree {
|
||||
if matches!(entry, WalkTreeEntry::NotBuilt) {
|
||||
*total_size += 1;
|
||||
}
|
||||
} else {
|
||||
if let WalkTreeEntry::Built(_p, pkg_size) = &entry {
|
||||
*total_size += pkg_size;
|
||||
}
|
||||
}
|
||||
let pkg_meta: Package;
|
||||
|
||||
let mut all_deps_set: HashSet<&PackageName> = HashSet::new();
|
||||
if let Ok(pkg_toml_str) = read_to_string(&pkg_toml) {
|
||||
// more accurate with auto deps
|
||||
pkg_meta = toml::from_str(&pkg_toml_str)
|
||||
.context(format!("Unable to parse {}", pkg_toml.display()))?;
|
||||
all_deps_set.extend(pkg_meta.depends.iter());
|
||||
} else {
|
||||
if is_build_tree {
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.package.dependencies.iter());
|
||||
} else {
|
||||
if let Ok(pkg_toml_str) = read_to_string(&pkg_toml) {
|
||||
// more accurate with auto deps
|
||||
pkg_meta = toml::from_str(&pkg_toml_str)
|
||||
.context(format!("Unable to parse {}", pkg_toml.display()))?;
|
||||
all_deps_set.extend(pkg_meta.depends.iter());
|
||||
}
|
||||
}
|
||||
|
||||
if all_deps_set.is_empty() {
|
||||
@ -97,6 +109,7 @@ pub fn walk_tree_entry(
|
||||
recipe_map,
|
||||
&format!("{}{}", prefix, child_prefix),
|
||||
i == deps_count - 1,
|
||||
is_build_tree,
|
||||
visited,
|
||||
total_size,
|
||||
op,
|
||||
@ -116,7 +129,7 @@ pub fn display_pkg_fn(
|
||||
WalkTreeEntry::Built(_path_buf, size) => format!("[{}]", format_size(*size)),
|
||||
WalkTreeEntry::NotBuilt => "(not built)".to_string(),
|
||||
WalkTreeEntry::Deduped => "".to_string(),
|
||||
WalkTreeEntry::Missing => "(dependency info missing)".to_string(),
|
||||
WalkTreeEntry::Missing => "(omitted)".to_string(),
|
||||
};
|
||||
let line_prefix = if is_last { "└── " } else { "├── " };
|
||||
println!("{}{}{} {}", prefix, line_prefix, package_name, size_str);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user