Merge branch 'mirrors' into 'master'

Add mirror config

See merge request redox-os/cookbook!650
This commit is contained in:
Jeremy Soller 2025-10-03 06:38:19 -06:00
commit fecbe0b11d
6 changed files with 142 additions and 3 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
/build
/repo
/cookbook.toml
source
source.tmp
source-new

View File

@ -18,6 +18,7 @@ path = "src/bin/cookbook_redoxer.rs"
[lib]
name = "cookbook"
path = "src/lib.rs"
doctest = false
[dependencies]
blake3 = "=1.5.3" # 1.5.4 is incompatible with blake3 0.3 dependency from pkgar

View File

@ -9,10 +9,11 @@ This repository contains the system source code and packages inside the `recipes
**Read [this](https://doc.redox-os.org/book/porting-applications.html) page before porting programs to Redox**
In order for this repository to be useful, it must be set up with an environment
from the [redox](https://gitlab.redox-os.org/redox-os/redox) repository.
from the [redox](https://gitlab.redox-os.org/redox-os/redox) repository or inside Redox OS with `cookbook` package.
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
- [Cookbook Config](#cookbook-config)
- [Recipe Categories](#recipe-categories)
- [Search Recipes](#search-recipes)
- [Package Policy](#package-policy)
@ -21,6 +22,21 @@ from the [redox](https://gitlab.redox-os.org/redox-os/redox) repository.
- [Repository Layout](#repository-layout)
- [TODO](#todo)
### Cookbook Config
Cookbook has special config to avoid repetitive args, place this file into `cookbook.toml` (in this cookbook directory, not redox build system) and configure it necessarily.
```toml
# Configuration file
# This is a configuration file to avoid repetitively spelling command args.
# At the moment only mirrors here implemented but in future it will be expanded when scripts are rusted
[[mirrors]]
# https://www.gnu.org/prep/ftp.en.html
"ftp.gnu.com" = "example.com/gnu"
"github.com/foo/bar" = "github.com/baz/bar"
```
### Recipe Categories
The categories inside the `recipes` folder.

View File

@ -1,4 +1,5 @@
use cookbook::blake3::blake3_progress;
use cookbook::config::{init_config, translate_mirror};
use cookbook::recipe::{AutoDeps, BuildKind, CookRecipe, Recipe, SourceRecipe};
use pkg::package::Package;
use pkg::{recipes, PackageName};
@ -369,7 +370,10 @@ fn fetch(recipe_dir: &Path, source: &Option<SourceRecipe>) -> Result<PathBuf, St
// Clone the repository to source.tmp
let mut command = Command::new("git");
command.arg("clone").arg("--recursive").arg(git);
command
.arg("clone")
.arg("--recursive")
.arg(translate_mirror(git));
if let Some(branch) = branch {
command.arg("--branch").arg(branch);
}
@ -516,7 +520,7 @@ fi"#,
let source_tar_tmp = recipe_dir.join("source.tar.tmp");
let mut command = Command::new("wget");
command.arg(tar);
command.arg(translate_mirror(tar));
command.arg("--continue").arg("-O").arg(&source_tar_tmp);
run_command(command)?;
@ -1374,6 +1378,7 @@ fn create_target_dir(recipe_dir: &Path) -> Result<PathBuf, String> {
}
fn main() {
init_config();
let mut matching = true;
let mut dry_run = false;
let mut fetch_only = false;

115
src/config.rs Normal file
View File

@ -0,0 +1,115 @@
use std::{collections::HashMap, fs, sync::OnceLock};
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct CookbookConfig {
pub mirrors: HashMap<String, String>,
}
static CONFIG: OnceLock<CookbookConfig> = OnceLock::new();
pub fn init_config() {
let config: CookbookConfig = {
let toml_content = fs::read_to_string("cookbook.toml").unwrap_or("".to_owned());
toml::from_str(&toml_content).unwrap_or(CookbookConfig::default())
};
CONFIG.set(config).expect("config is initialized twice");
}
pub fn translate_mirror(original_url: &str) -> String {
let config = CONFIG.get().expect("Configuration is not initialized");
let stripped_url = original_url
.strip_prefix("https://")
.or_else(|| original_url.strip_prefix("http://"))
.unwrap_or(original_url);
let mut best_match_prefix: Option<&String> = None;
for prefix in config.mirrors.keys() {
if stripped_url.starts_with(prefix) {
match best_match_prefix {
Some(current_best) if prefix.len() > current_best.len() => {
best_match_prefix = Some(prefix);
}
None => {
best_match_prefix = Some(prefix);
}
_ => {}
}
}
}
if let Some(prefix) = best_match_prefix {
let mirror_base = config.mirrors.get(prefix).unwrap();
let suffix = &stripped_url[prefix.len()..];
let ptotocol = &original_url[..(original_url.len() - stripped_url.len())];
return format!("{}{}{}", ptotocol, mirror_base, suffix);
}
original_url.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
fn setup_test_config() {
let mut mirrors = HashMap::new();
mirrors.insert("ftp.gnu.com".to_string(), "example.com/gnu".to_string());
mirrors.insert(
"github.com/foo/bar".to_string(),
"github.com/baz/bar".to_string(),
);
mirrors.insert("github.com/a".to_string(), "github.com/b".to_string());
let app_config = CookbookConfig { mirrors };
// This will be called for each test. If the config is already set,
// it will do nothing, which is fine as all tests use the same config.
let _ = CONFIG.set(app_config);
}
#[test]
fn test_exact_match() {
setup_test_config();
assert_eq!(translate_mirror("ftp.gnu.com"), "example.com/gnu");
assert_eq!(translate_mirror("github.com/foo/bar"), "github.com/baz/bar");
}
#[test]
fn test_prefix_match() {
setup_test_config();
assert_eq!(
translate_mirror("https://github.com/a/c"),
"https://github.com/b/c"
);
assert_eq!(
translate_mirror("https://ftp.gnu.com/path/to/file"),
"https://example.com/gnu/path/to/file"
);
}
#[test]
fn test_longest_prefix_match() {
setup_test_config();
// "github.com/foo/bar" is a longer and more specific prefix than "github.com/a",
// so it should be chosen for the translation.
assert_eq!(
translate_mirror("https://github.com/foo/bar/baz"),
"https://github.com/baz/bar/baz"
);
}
#[test]
fn test_no_match() {
setup_test_config();
assert_eq!(translate_mirror("www.rust-lang.org"), "www.rust-lang.org");
assert_eq!(
translate_mirror("http://github.com/unrelated/repo"),
"http://github.com/unrelated/repo"
);
}
}

View File

@ -1,4 +1,5 @@
pub mod blake3;
pub mod config;
pub mod recipe;
mod progress_bar;