mirror of
https://gitlab.redox-os.org/redox-os/redox.git
synced 2026-06-17 15:34:18 +08:00
Merge branch 'mirrors' into 'master'
Add mirror config See merge request redox-os/cookbook!650
This commit is contained in:
commit
fecbe0b11d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/build
|
||||
/repo
|
||||
/cookbook.toml
|
||||
source
|
||||
source.tmp
|
||||
source-new
|
||||
|
||||
@ -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
|
||||
|
||||
18
README.md
18
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.
|
||||
|
||||
[](./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.
|
||||
|
||||
@ -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
115
src/config.rs
Normal 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"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
pub mod blake3;
|
||||
pub mod config;
|
||||
pub mod recipe;
|
||||
|
||||
mod progress_bar;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user