From c51fad08ff420e0819923d20052a27c3e5208925 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 3 Oct 2025 13:55:38 +0700 Subject: [PATCH 1/2] Add mirror config --- .gitignore | 1 + Cargo.toml | 1 + README.md | 18 +++++++- src/bin/cook.rs | 6 ++- src/config.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 6 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 src/config.rs diff --git a/.gitignore b/.gitignore index b172da92..c1ecfbf9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /build /repo +/cookbook.toml source source.tmp source-new diff --git a/Cargo.toml b/Cargo.toml index 9376f661..b4695bef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/README.md b/README.md index 45af8844..7cba4907 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 5dd888d5..267c4c66 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -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,7 @@ fn fetch(recipe_dir: &Path, source: &Option) -> Result Result { } fn main() { + init_config(); let mut matching = true; let mut dry_run = false; let mut fetch_only = false; diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 00000000..fb07ce2a --- /dev/null +++ b/src/config.rs @@ -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, +} + +static CONFIG: OnceLock = 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" + ); + } +} diff --git a/src/lib.rs b/src/lib.rs index 5a0b3fff..0afa53ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod blake3; pub mod recipe; +pub mod config; mod progress_bar; From 26e6e0dc068ad7f3cc49139f4c2edc70c91a4d8c Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 3 Oct 2025 13:59:14 +0700 Subject: [PATCH 2/2] fmt --- src/bin/cook.rs | 5 ++++- src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 267c4c66..437c00b6 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -370,7 +370,10 @@ fn fetch(recipe_dir: &Path, source: &Option) -> Result