mirror of
https://gitlab.redox-os.org/redox-os/redox.git
synced 2026-06-17 23:44:17 +08:00
Merge branch 'reuse-pkgutils-package-struct' into 'master'
Move struct Package to redox-pkg See merge request redox-os/cookbook!521
This commit is contained in:
commit
006ac4b73a
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -1830,6 +1830,22 @@ dependencies = [
|
||||
"toml 0.8.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-pkg"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ignore",
|
||||
"pkgar 0.1.15",
|
||||
"pkgar-core 0.1.15",
|
||||
"pkgar-keys 0.1.15",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"thiserror 1.0.69",
|
||||
"toml 0.8.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.2.4"
|
||||
@ -1851,6 +1867,7 @@ dependencies = [
|
||||
"pkgar 0.1.17",
|
||||
"pkgar-core 0.1.17",
|
||||
"pkgar-keys 0.1.17",
|
||||
"redox-pkg 0.2.5",
|
||||
"redoxer",
|
||||
"serde",
|
||||
"tempfile",
|
||||
@ -1876,7 +1893,7 @@ dependencies = [
|
||||
"pkgar-core 0.1.15",
|
||||
"pkgar-keys 0.1.15",
|
||||
"rand",
|
||||
"redox-pkg",
|
||||
"redox-pkg 0.2.4",
|
||||
"redox_liner",
|
||||
"redox_syscall",
|
||||
"redoxfs",
|
||||
|
||||
@ -27,6 +27,7 @@ pbr = "1.0.2"
|
||||
pkgar = { path = "pkgar/pkgar" }
|
||||
pkgar-core = { path = "pkgar/pkgar-core" }
|
||||
pkgar-keys = { path = "pkgar/pkgar-keys" }
|
||||
redox-pkg = { git = "https://gitlab.redox-os.org/redox-os/pkgutils" }
|
||||
redoxer = "0.2"
|
||||
serde = { version = "=1.0.197", features = ["derive"] }
|
||||
termion = "4"
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use cookbook::blake3::blake3_progress;
|
||||
use cookbook::package::StageToml;
|
||||
use cookbook::recipe::{BuildKind, CookRecipe, Recipe, SourceRecipe};
|
||||
use cookbook::recipe_find::recipe_find;
|
||||
use pkg::package::Package;
|
||||
use pkg::{recipes, PackageName};
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryInto;
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
env, fs,
|
||||
@ -15,6 +16,8 @@ use std::{
|
||||
use termion::{color, style};
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
use cookbook::WALK_DEPTH;
|
||||
|
||||
fn remove_all(path: &Path) -> Result<(), String> {
|
||||
if path.is_dir() {
|
||||
fs::remove_dir_all(path)
|
||||
@ -504,7 +507,10 @@ fi"#,
|
||||
Ok(source_dir)
|
||||
}
|
||||
|
||||
fn auto_deps(stage_dir: &Path, dep_pkgars: &BTreeSet<(String, PathBuf)>) -> BTreeSet<String> {
|
||||
fn auto_deps(
|
||||
stage_dir: &Path,
|
||||
dep_pkgars: &BTreeSet<(PackageName, PathBuf)>,
|
||||
) -> BTreeSet<PackageName> {
|
||||
let mut paths = BTreeSet::new();
|
||||
let mut visited = BTreeSet::new();
|
||||
// Base directories may need to be updated for packages that place binaries in odd locations.
|
||||
@ -571,7 +577,12 @@ fn auto_deps(stage_dir: &Path, dep_pkgars: &BTreeSet<(String, PathBuf)>) -> BTre
|
||||
if let Ok(relative_path) = path.strip_prefix(stage_dir) {
|
||||
eprintln!("DEBUG: {} needs {}", relative_path.display(), name);
|
||||
}
|
||||
needed.insert(name.to_string());
|
||||
if let Ok(name) = PackageName::new(name) {
|
||||
needed.insert(name);
|
||||
} else {
|
||||
// AFAICT this shouldn't ever happen.
|
||||
eprintln!("ERROR: `{name}` is an invalid package name; please report");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -623,18 +634,17 @@ fn build(
|
||||
recipe_dir: &Path,
|
||||
source_dir: &Path,
|
||||
target_dir: &Path,
|
||||
name: &str,
|
||||
name: &PackageName,
|
||||
recipe: &Recipe,
|
||||
) -> Result<(PathBuf, BTreeSet<String>), String> {
|
||||
) -> Result<(PathBuf, BTreeSet<PackageName>), String> {
|
||||
let mut dep_pkgars = BTreeSet::new();
|
||||
for dependency in recipe.build.dependencies.iter() {
|
||||
//TODO: sanitize name
|
||||
let dependency_dir = recipe_find(dependency);
|
||||
let dependency_dir = recipes::find(dependency.as_str());
|
||||
if dependency_dir.is_none() {
|
||||
return Err(format!("failed to find recipe directory '{}'", dependency));
|
||||
}
|
||||
dep_pkgars.insert((
|
||||
dependency.to_string(),
|
||||
dependency.clone(),
|
||||
dependency_dir
|
||||
.unwrap()
|
||||
.join("target")
|
||||
@ -992,7 +1002,7 @@ done
|
||||
command.arg("bash").arg("-ex");
|
||||
command.current_dir(&cookbook_build);
|
||||
command.env("COOKBOOK_BUILD", &cookbook_build);
|
||||
command.env("COOKBOOK_NAME", name);
|
||||
command.env("COOKBOOK_NAME", name.as_str());
|
||||
command.env("COOKBOOK_RECIPE", &cookbook_recipe);
|
||||
command.env("COOKBOOK_REDOXER", &cookbook_redoxer);
|
||||
command.env("COOKBOOK_ROOT", &cookbook_root);
|
||||
@ -1022,9 +1032,9 @@ fn package(
|
||||
_recipe_dir: &Path,
|
||||
stage_dir: &Path,
|
||||
target_dir: &Path,
|
||||
name: &str,
|
||||
name: &PackageName,
|
||||
recipe: &Recipe,
|
||||
auto_deps: &BTreeSet<String>,
|
||||
auto_deps: &BTreeSet<PackageName>,
|
||||
) -> Result<PathBuf, String> {
|
||||
//TODO: metadata like dependencies, name, and version
|
||||
let package = &recipe.package;
|
||||
@ -1072,8 +1082,8 @@ fn package(
|
||||
depends.push(dep.clone());
|
||||
}
|
||||
}
|
||||
let stage_toml = toml::to_string(&StageToml {
|
||||
name: name.into(),
|
||||
let stage_toml = toml::to_string(&Package {
|
||||
name: name.clone(),
|
||||
version: "TODO".into(),
|
||||
target: env::var("TARGET")
|
||||
.map_err(|err| format!("failed to read TARGET: {:?}", err))?,
|
||||
@ -1087,7 +1097,12 @@ fn package(
|
||||
Ok(package_file)
|
||||
}
|
||||
|
||||
fn cook(recipe_dir: &Path, name: &str, recipe: &Recipe, fetch_only: bool) -> Result<(), String> {
|
||||
fn cook(
|
||||
recipe_dir: &Path,
|
||||
name: &PackageName,
|
||||
recipe: &Recipe,
|
||||
fetch_only: bool,
|
||||
) -> Result<(), String> {
|
||||
let source_dir =
|
||||
fetch(recipe_dir, &recipe.source).map_err(|err| format!("failed to fetch: {}", err))?;
|
||||
|
||||
@ -1104,7 +1119,7 @@ fn cook(recipe_dir: &Path, name: &str, recipe: &Recipe, fetch_only: bool) -> Res
|
||||
create_dir(&target_dir)?;
|
||||
}
|
||||
|
||||
let (stage_dir, auto_deps) = build(recipe_dir, &source_dir, &target_dir, name, &recipe)
|
||||
let (stage_dir, auto_deps) = build(recipe_dir, &source_dir, &target_dir, name, recipe)
|
||||
.map_err(|err| format!("failed to build: {}", err))?;
|
||||
|
||||
let _package_file = package(
|
||||
@ -1112,7 +1127,7 @@ fn cook(recipe_dir: &Path, name: &str, recipe: &Recipe, fetch_only: bool) -> Res
|
||||
&stage_dir,
|
||||
&target_dir,
|
||||
name,
|
||||
&recipe,
|
||||
recipe,
|
||||
&auto_deps,
|
||||
)
|
||||
.map_err(|err| format!("failed to package: {}", err))?;
|
||||
@ -1134,12 +1149,12 @@ fn main() {
|
||||
"--with-package-deps" if matching => with_package_deps = true,
|
||||
"--fetch-only" if matching => fetch_only = true,
|
||||
"-q" | "--quiet" if matching => quiet = true,
|
||||
_ => recipe_names.push(arg),
|
||||
_ => recipe_names.push(arg.try_into().expect("Invalid package name")),
|
||||
}
|
||||
}
|
||||
|
||||
if with_package_deps {
|
||||
recipe_names = match CookRecipe::get_package_deps_recursive(&recipe_names, 16) {
|
||||
recipe_names = match CookRecipe::get_package_deps_recursive(&recipe_names, WALK_DEPTH) {
|
||||
Ok(ok) => ok,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
@ -1155,7 +1170,7 @@ fn main() {
|
||||
};
|
||||
}
|
||||
|
||||
let recipes = match CookRecipe::new_recursive(&recipe_names, 16) {
|
||||
let recipes = match CookRecipe::new_recursive(&recipe_names, WALK_DEPTH) {
|
||||
Ok(ok) => ok,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use cookbook::recipe_find::recipe_find;
|
||||
use std::env::args;
|
||||
use std::process::exit;
|
||||
// use clap::Parser;
|
||||
|
||||
use pkg::recipes;
|
||||
|
||||
fn usage() {
|
||||
println!("Usage: find_recipe recipe_name");
|
||||
@ -12,14 +12,14 @@ fn main() {
|
||||
exit(2);
|
||||
}
|
||||
let recipe_name = &args().last().unwrap();
|
||||
match recipe_find(recipe_name) {
|
||||
match recipes::find(recipe_name) {
|
||||
Some(path) => {
|
||||
println!("{}", path.display());
|
||||
exit(0);
|
||||
},
|
||||
}
|
||||
None => {
|
||||
eprintln!("recipe {} not found", recipe_name);
|
||||
exit(1);
|
||||
eprintln!("recipe {} not found", recipe_name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
use cookbook::recipe_find::list_recipes;
|
||||
use std::process::exit;
|
||||
// use clap::Parser;
|
||||
|
||||
use pkg::recipes;
|
||||
|
||||
fn main() {
|
||||
let print_short = std::env::args()
|
||||
.nth(1)
|
||||
.map_or(false, |a| a == "-s" || a == "--short");
|
||||
|
||||
let result = list_recipes(Default::default());
|
||||
let result = recipes::list("");
|
||||
if result.is_empty() {
|
||||
eprintln!("recipes not found");
|
||||
exit(1);
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
use cookbook::package::StageToml;
|
||||
use std::{env::args, process::ExitCode};
|
||||
|
||||
/// Same as `cookbook/src/bin/cook.rs`.
|
||||
const DEP_DEPTH: usize = 16;
|
||||
use pkg::package::Package;
|
||||
|
||||
use cookbook::WALK_DEPTH;
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let names = args().skip(1).collect::<Vec<String>>();
|
||||
let packages = StageToml::new_recursive(&names, DEP_DEPTH).expect("package not found");
|
||||
// TODO: Ugly vec
|
||||
let names: Vec<&str> = names.iter().map(|s| s.as_str()).collect();
|
||||
let packages = Package::new_recursive(&names, WALK_DEPTH).expect("package not found");
|
||||
|
||||
for package in packages {
|
||||
println!("{}", package.name);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
pub mod blake3;
|
||||
pub mod package;
|
||||
pub mod recipe;
|
||||
pub mod recipe_find;
|
||||
|
||||
mod progress_bar;
|
||||
|
||||
/// Default for maximum number of levels to descend down dependencies tree.
|
||||
pub const WALK_DEPTH: usize = 16;
|
||||
|
||||
@ -1,77 +0,0 @@
|
||||
use std::{env, fs};
|
||||
|
||||
use crate::recipe_find::recipe_find;
|
||||
|
||||
//TODO: share struct with pkgutils?
|
||||
#[derive(PartialEq, serde::Deserialize, serde::Serialize)]
|
||||
pub struct StageToml {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub target: String,
|
||||
pub depends: Vec<String>,
|
||||
}
|
||||
|
||||
impl StageToml {
|
||||
pub fn new(name: String) -> Result<Self, String> {
|
||||
//TODO: sanitize recipe name?
|
||||
let dir = recipe_find(&name);
|
||||
if dir.is_none() {
|
||||
return Err(format!("failed to find recipe directory '{}'", name));
|
||||
}
|
||||
let dir = dir.unwrap();
|
||||
let target =
|
||||
env::var("TARGET").map_err(|err| format!("failed to read TARGET: {:?}", err))?;
|
||||
|
||||
let file = dir.join("target").join(target).join("stage.toml");
|
||||
if !file.is_file() {
|
||||
return Err(format!("failed to find package file '{}'", file.display()));
|
||||
}
|
||||
|
||||
let toml = fs::read_to_string(&file).map_err(|err| {
|
||||
format!(
|
||||
"failed to read package file '{}': {}\n{:#?}",
|
||||
file.display(),
|
||||
err,
|
||||
err
|
||||
)
|
||||
})?;
|
||||
|
||||
toml::from_str(&toml).map_err(|err| {
|
||||
format!(
|
||||
"failed to parse package file '{}': {}\n{:#?}",
|
||||
file.display(),
|
||||
err,
|
||||
err
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_recursive(names: &[String], recursion: usize) -> Result<Vec<Self>, String> {
|
||||
if recursion == 0 {
|
||||
return Err(format!(
|
||||
"recursion limit while processing build dependencies: {:#?}",
|
||||
names
|
||||
));
|
||||
}
|
||||
|
||||
let mut packages = Vec::new();
|
||||
for name in names {
|
||||
let package = Self::new(name.clone())?;
|
||||
|
||||
let dependencies = Self::new_recursive(&package.depends, recursion - 1)
|
||||
.map_err(|err| format!("{}: failed on loading dependencies:\n{}", name, err))?;
|
||||
|
||||
for dependency in dependencies {
|
||||
if !packages.contains(&dependency) {
|
||||
packages.push(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
if !packages.contains(&package) {
|
||||
packages.push(package);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(packages)
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,8 @@
|
||||
use std::{
|
||||
fs,
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::{convert::TryInto, fs, path::PathBuf};
|
||||
|
||||
use pkg::{recipes, PackageName};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::recipe_find::recipe_find;
|
||||
|
||||
/// Specifies how to download the source for a recipe
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(untagged)]
|
||||
@ -83,19 +79,19 @@ pub struct BuildRecipe {
|
||||
#[serde(flatten)]
|
||||
pub kind: BuildKind,
|
||||
#[serde(default)]
|
||||
pub dependencies: Vec<String>,
|
||||
pub dependencies: Vec<PackageName>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
|
||||
pub struct PackageRecipe {
|
||||
#[serde(default)]
|
||||
pub dependencies: Vec<String>,
|
||||
pub dependencies: Vec<PackageName>,
|
||||
}
|
||||
|
||||
/// Everything required to build a Redox package
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct Recipe {
|
||||
/// Specifies how to donload the source for this recipe
|
||||
/// Specifies how to download the source for this recipe
|
||||
pub source: Option<SourceRecipe>,
|
||||
/// Specifies how to build this recipe
|
||||
pub build: BuildRecipe,
|
||||
@ -106,15 +102,17 @@ pub struct Recipe {
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct CookRecipe {
|
||||
pub name: String,
|
||||
pub name: PackageName,
|
||||
pub dir: PathBuf,
|
||||
pub recipe: Recipe,
|
||||
}
|
||||
|
||||
impl CookRecipe {
|
||||
pub fn new(name: String) -> Result<Self, String> {
|
||||
//TODO: sanitize recipe name?
|
||||
let dir = recipe_find(&name);
|
||||
pub fn new(name: &str) -> Result<Self, String> {
|
||||
let name: PackageName = name
|
||||
.try_into()
|
||||
.map_err(|e| format!("Invalid package name: {e}"))?;
|
||||
let dir = recipes::find(name.as_str());
|
||||
if dir.is_none() {
|
||||
return Err(format!("failed to find recipe directory '{}'", name));
|
||||
}
|
||||
@ -142,10 +140,11 @@ impl CookRecipe {
|
||||
)
|
||||
})?;
|
||||
|
||||
let dir = dir.to_path_buf();
|
||||
Ok(Self { name, dir, recipe })
|
||||
}
|
||||
|
||||
pub fn new_recursive(names: &[String], recursion: usize) -> Result<Vec<Self>, String> {
|
||||
pub fn new_recursive(names: &[PackageName], recursion: usize) -> Result<Vec<Self>, String> {
|
||||
if recursion == 0 {
|
||||
return Err(format!(
|
||||
"recursion limit while processing build dependencies: {:#?}",
|
||||
@ -155,7 +154,7 @@ impl CookRecipe {
|
||||
|
||||
let mut recipes = Vec::new();
|
||||
for name in names {
|
||||
let recipe = Self::new(name.clone())?;
|
||||
let recipe = Self::new(name.as_str())?;
|
||||
|
||||
let dependencies =
|
||||
Self::new_recursive(&recipe.recipe.build.dependencies, recursion - 1).map_err(
|
||||
@ -176,7 +175,10 @@ impl CookRecipe {
|
||||
Ok(recipes)
|
||||
}
|
||||
|
||||
pub fn get_package_deps_recursive(names: &[String], recursion: usize) -> Result<Vec<String>, String> {
|
||||
pub fn get_package_deps_recursive(
|
||||
names: &[PackageName],
|
||||
recursion: usize,
|
||||
) -> Result<Vec<PackageName>, String> {
|
||||
if recursion == 0 {
|
||||
return Err(format!(
|
||||
"recursion limit while processing package dependencies: {:#?}",
|
||||
@ -184,14 +186,15 @@ impl CookRecipe {
|
||||
));
|
||||
}
|
||||
|
||||
let mut recipes = Vec::new();
|
||||
let mut recipes: Vec<PackageName> = Vec::new();
|
||||
for name in names {
|
||||
let recipe = Self::new(name.clone())?;
|
||||
let recipe = Self::new(name.as_str())?;
|
||||
|
||||
let dependencies =
|
||||
Self::get_package_deps_recursive(&recipe.recipe.package.dependencies, recursion - 1).map_err(
|
||||
|err| format!("{}: failed on loading package dependencies:\n{}", name, err),
|
||||
)?;
|
||||
let dependencies = Self::get_package_deps_recursive(
|
||||
&recipe.recipe.package.dependencies,
|
||||
recursion - 1,
|
||||
)
|
||||
.map_err(|err| format!("{}: failed on loading package dependencies:\n{}", name, err))?;
|
||||
|
||||
for dependency in dependencies {
|
||||
if !recipes.contains(&dependency) {
|
||||
@ -199,7 +202,7 @@ impl CookRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
if !recipes.contains(&name) {
|
||||
if !recipes.contains(name) {
|
||||
recipes.push(name.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static RECIPE_PATHS: LazyLock<HashMap<String, PathBuf>> = LazyLock::new(|| {
|
||||
let mut recipe_paths = HashMap::new();
|
||||
for entry_res in ignore::Walk::new("recipes") {
|
||||
let entry = entry_res.unwrap();
|
||||
if entry.file_name() == OsStr::new("recipe.sh") || entry.file_name() == OsStr::new("recipe.toml") {
|
||||
let recipe_file = entry.path();
|
||||
let Some(recipe_dir) = recipe_file.parent() else { continue };
|
||||
let Some(recipe_name) = recipe_dir.file_name().and_then(|x| x.to_str()) else { continue };
|
||||
if let Some(other_dir) = recipe_paths.insert(recipe_name.to_string(), recipe_dir.to_path_buf()) {
|
||||
panic!(
|
||||
"recipe {} has two or more entries {:?}, {:?}",
|
||||
recipe_name,
|
||||
other_dir,
|
||||
recipe_dir
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
recipe_paths
|
||||
});
|
||||
|
||||
pub fn recipe_find(recipe: &str) -> Option<PathBuf> {
|
||||
RECIPE_PATHS.get(recipe).cloned()
|
||||
}
|
||||
|
||||
pub fn list_recipes(prefix: PathBuf) -> Vec<PathBuf> {
|
||||
let mut recipes = Vec::<PathBuf>::new();
|
||||
for (_name, path) in RECIPE_PATHS.iter() {
|
||||
recipes.push(prefix.join(path));
|
||||
}
|
||||
recipes.sort();
|
||||
recipes
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user