use std::{
env, fs,
io::Write,
path::{Path, PathBuf},
};
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let explorer = env::var_os("CARGO_FEATURE_EXPLORER").is_some();
let docs = env::var_os("CARGO_FEATURE_DOCS").is_some();
if !explorer && !docs {
return;
}
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let manifest_dir = Path::new(&manifest_dir);
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
let out_dir = Path::new(&out_dir);
stage_duckdb_vendor(
&manifest_dir.join("../../docs/src/assets/vendor/duckdb"),
&out_dir.join("duckdb_vendor"),
);
if docs {
stage_docs_site(
&manifest_dir.join("../../docs/site"),
&out_dir.join("docs_site"),
);
}
}
fn stage_duckdb_vendor(src_dir: &Path, dst_dir: &Path) {
println!("cargo:rerun-if-changed={}", src_dir.display());
let _ = fs::remove_dir_all(dst_dir);
fs::create_dir_all(dst_dir).expect("create duckdb_vendor out dir");
for entry in fs::read_dir(src_dir).expect("read vendored duckdb dir") {
let entry = entry.expect("read dir entry");
let path = entry.path();
if !path.is_file() {
continue;
}
println!("cargo:rerun-if-changed={}", path.display());
let file_name = entry.file_name();
let name = file_name.to_string_lossy();
let bytes = fs::read(&path).expect("read vendored asset");
if name.ends_with(".wasm") {
let gz_path = dst_dir.join(format!("{name}.gz"));
let file = fs::File::create(&gz_path).expect("create gzipped asset");
let mut encoder = flate2::write::GzEncoder::new(file, flate2::Compression::best());
encoder.write_all(&bytes).expect("gzip write");
encoder.finish().expect("gzip finish");
} else {
fs::write(dst_dir.join(name.as_ref()), &bytes).expect("copy asset");
}
}
}
fn stage_docs_site(src_dir: &Path, dst_dir: &Path) {
println!("cargo:rerun-if-changed={}", src_dir.display());
let _ = fs::remove_dir_all(dst_dir);
fs::create_dir_all(dst_dir).expect("create docs_site out dir");
copy_tree(src_dir, dst_dir);
}
fn copy_tree(src: &Path, dst: &Path) {
for entry in fs::read_dir(src).expect("read docs site dir") {
let entry = entry.expect("read dir entry");
let path = entry.path();
let name = entry.file_name();
let target: PathBuf = dst.join(&name);
if path.is_dir() {
fs::create_dir_all(&target).expect("create docs subdir");
copy_tree(&path, &target);
} else if path.is_file() {
if name.to_string_lossy().ends_with(".wasm") {
continue;
}
fs::copy(&path, &target).expect("copy docs file");
}
}
}