mirror of
https://gitlab.redox-os.org/redox-os/redox.git
synced 2026-06-17 15:34:18 +08:00
web: Implement file index
This commit is contained in:
parent
4d30dceba0
commit
771df295c5
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -885,6 +885,7 @@ dependencies = [
|
||||
"redoxer",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strip-ansi-escapes",
|
||||
"termion",
|
||||
"toml",
|
||||
@ -1018,24 +1019,47 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
@ -1458,3 +1482,9 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
|
||||
@ -42,12 +42,13 @@ redox-pkg = { git = "https://gitlab.redox-os.org/redox-os/pkgutils.git", default
|
||||
redox_installer = { git = "https://gitlab.redox-os.org/redox-os/installer.git", default-features = false }
|
||||
redoxer = { git = "https://gitlab.redox-os.org/redox-os/redoxer.git", default-features = false }
|
||||
regex = "1.11"
|
||||
serde = { version = "=1.0.197", features = ["derive"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
termion = "4"
|
||||
toml = "0.8"
|
||||
walkdir = "2.3.1"
|
||||
ansi-to-tui = { version = "8", optional = true }
|
||||
strip-ansi-escapes = { version = "0.2.1", optional = true }
|
||||
serde_json = "1"
|
||||
|
||||
[dependencies.ratatui]
|
||||
version = "0.30"
|
||||
|
||||
17
src/web.rs
17
src/web.rs
@ -13,6 +13,7 @@ use crate::{
|
||||
};
|
||||
|
||||
pub mod html;
|
||||
pub mod search;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CliWebConfig {
|
||||
@ -58,6 +59,7 @@ pub fn generate_web(all_packages: &Vec<String>, config: &CliWebConfig) {
|
||||
|
||||
let mut valid_packages = Vec::new();
|
||||
let mut dependents_map: HashMap<String, BTreeSet<String>> = HashMap::new();
|
||||
let mut files_map: BTreeMap<String, String> = BTreeMap::new();
|
||||
|
||||
for package_name in all_packages {
|
||||
let Ok(package_name) = PackageName::new(package_name) else {
|
||||
@ -108,6 +110,10 @@ pub fn generate_web(all_packages: &Vec<String>, config: &CliWebConfig) {
|
||||
&html_path,
|
||||
&config,
|
||||
);
|
||||
|
||||
if let Some(file_map) = stage_files {
|
||||
files_map.insert(package.name.to_string(), file_map);
|
||||
}
|
||||
}
|
||||
|
||||
let mut grouped_packages: BTreeMap<String, Vec<&(Package, CookRecipe)>> = BTreeMap::new();
|
||||
@ -120,7 +126,16 @@ pub fn generate_web(all_packages: &Vec<String>, config: &CliWebConfig) {
|
||||
let index_path = repo_path.join("index.html");
|
||||
let style_path = repo_path.join("style.css");
|
||||
generate_html_index(grouped_packages, &index_path, &config);
|
||||
fs::write(style_path, CSS).expect("Failed to write CSS file");
|
||||
fs::write(style_path, CSS).expect("Failed to write style.css");
|
||||
|
||||
let mut index_files = search::FileIndexBuilder::new();
|
||||
for (package, files) in &files_map {
|
||||
index_files.parse(package, files);
|
||||
}
|
||||
let files_path = repo_path.join("files.json");
|
||||
index_files
|
||||
.write(&files_path)
|
||||
.expect("Failed to write files.json");
|
||||
}
|
||||
|
||||
pub(crate) fn get_category(dir: &Path) -> String {
|
||||
|
||||
113
src/web/search.rs
Normal file
113
src/web/search.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{Result, wrap_io_err};
|
||||
|
||||
#[derive(Serialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
enum FsNode {
|
||||
Dir(BTreeMap<String, FsNode>),
|
||||
File(String),
|
||||
}
|
||||
|
||||
pub struct FileIndexBuilder {
|
||||
inner: BTreeMap<String, FsNode>,
|
||||
}
|
||||
impl FileIndexBuilder {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
inner: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
fn insert_node(&mut self, path_stack: &[String], name: &str, pkg_name: Option<&str>) {
|
||||
let mut current = &mut self.inner;
|
||||
for dir in path_stack {
|
||||
let node = current
|
||||
.entry(dir.clone())
|
||||
.or_insert_with(|| FsNode::Dir(BTreeMap::new()));
|
||||
|
||||
if let FsNode::File(_) = node {
|
||||
// previously a file, silently replace to dir
|
||||
*node = FsNode::Dir(BTreeMap::new());
|
||||
}
|
||||
|
||||
match node {
|
||||
FsNode::Dir(map) => current = map,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pkg) = pkg_name {
|
||||
current
|
||||
.entry(name.to_string())
|
||||
.and_modify(|node| {
|
||||
if let FsNode::File(existing_pkgs) = node {
|
||||
existing_pkgs.push(',');
|
||||
existing_pkgs.push_str(pkg);
|
||||
} else {
|
||||
*node = FsNode::File(pkg.to_string());
|
||||
}
|
||||
})
|
||||
.or_insert_with(|| FsNode::File(pkg.to_string()));
|
||||
} else {
|
||||
current
|
||||
.entry(name.to_string())
|
||||
.or_insert_with(|| FsNode::Dir(BTreeMap::new()));
|
||||
}
|
||||
}
|
||||
pub fn parse(&mut self, pkg: &str, content: &str) {
|
||||
let mut path_stack: Vec<String> = Vec::new();
|
||||
|
||||
for line in content.lines() {
|
||||
if line.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut prefix_chars: usize = 0;
|
||||
let mut name_start_byte = 0;
|
||||
|
||||
for (idx, c) in line.char_indices() {
|
||||
if "│├└─ ".contains(c) {
|
||||
prefix_chars += 1;
|
||||
} else {
|
||||
name_start_byte = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if name_start_byte == 0 && prefix_chars == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let depth = (prefix_chars / 4).saturating_sub(1);
|
||||
let remainder = line[name_start_byte..].trim();
|
||||
|
||||
path_stack.truncate(depth);
|
||||
|
||||
if remainder.ends_with('/') {
|
||||
let name = remainder.trim_end_matches('/');
|
||||
self.insert_node(&path_stack, name, None);
|
||||
path_stack.push(name.to_string());
|
||||
} else {
|
||||
let name = if let Some(paren_idx) = remainder.rfind('(') {
|
||||
// Strip size
|
||||
remainder[..paren_idx].trim()
|
||||
} else {
|
||||
remainder
|
||||
};
|
||||
self.insert_node(&path_stack, name, Some(pkg));
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn write(&self, path: &Path) -> Result<()> {
|
||||
// JSON: because javascript have them natively
|
||||
let json_output = serde_json::to_string(&self.inner).unwrap();
|
||||
let mut file = File::create(path).map_err(wrap_io_err!(path, "Opening file"))?;
|
||||
file.write_all(json_output.as_bytes())
|
||||
.map_err(wrap_io_err!(path, "Writing file"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user