#![warn(missing_docs)]
use anyhow::{Context, Error};
use clap::{Args, Parser, Subcommand};
use std::{io::stdin, path::PathBuf};
use web_static_pack_packer::{directory, file, file_pack_path, pack};
#[derive(Parser, Debug)]
#[command(version, about)]
struct Arguments {
#[command(subcommand)]
pub command: Command,
}
#[derive(Args, Debug)]
struct FileGlobalOptions {
#[arg(long)]
pub use_gzip: Option<bool>,
#[arg(long)]
pub use_brotli: Option<bool>,
}
impl FileGlobalOptions {
pub fn into_file_build_from_path_options(self) -> file::BuildFromPathOptions {
let mut file_build_from_path_options = file::BuildFromPathOptions::default();
if let Some(use_gzip) = self.use_gzip {
file_build_from_path_options.use_gzip = use_gzip;
}
if let Some(use_brotli) = self.use_brotli {
file_build_from_path_options.use_brotli = use_brotli;
}
file_build_from_path_options
}
}
#[derive(Subcommand, Debug)]
enum Command {
DirectorySingle {
#[command(flatten)]
file_global_options: FileGlobalOptions,
#[arg(long)]
follow_links: Option<bool>,
input_directory_path: PathBuf,
output_file_path: PathBuf,
},
FilesCmd {
#[command(flatten)]
file_global_options: FileGlobalOptions,
output_file_path: PathBuf,
input_base_directory_path: PathBuf,
input_file_paths: Vec<PathBuf>,
},
FilesStdin {
#[command(flatten)]
file_global_options: FileGlobalOptions,
input_base_directory_path: PathBuf,
output_file_path: PathBuf,
},
}
fn main() -> Result<(), Error> {
let arguments = Arguments::parse();
match arguments.command {
Command::DirectorySingle {
file_global_options,
follow_links,
input_directory_path,
output_file_path,
} => {
let mut directory_search_options = directory::SearchOptions::default();
if let Some(follow_links) = follow_links {
directory_search_options.follow_links = follow_links;
}
let file_build_from_path_options =
file_global_options.into_file_build_from_path_options();
let mut pack_builder = pack::Builder::new();
for file_pack_path in directory::search(
&input_directory_path,
&directory_search_options,
&file_build_from_path_options,
)? {
pack_builder.file_pack_path_add(file_pack_path)?
}
let pack = pack_builder.finalize();
pack::store_file(&pack, &output_file_path)?;
}
Command::FilesCmd {
file_global_options,
output_file_path,
input_base_directory_path,
input_file_paths,
} => {
let file_build_from_path_options =
file_global_options.into_file_build_from_path_options();
let mut pack_builder = pack::Builder::new();
for input_file_path in input_file_paths {
let input_file_error_context = || input_file_path.to_string_lossy().into_owned();
let file_pack_path = file_pack_path::FilePackPath::build_from_path(
&input_file_path,
&input_base_directory_path,
&file_build_from_path_options,
)
.with_context(input_file_error_context)?;
pack_builder
.file_pack_path_add(file_pack_path)
.with_context(input_file_error_context)?;
}
let pack = pack_builder.finalize();
pack::store_file(&pack, &output_file_path)?;
}
Command::FilesStdin {
file_global_options,
input_base_directory_path,
output_file_path,
} => {
let file_build_from_path_options =
file_global_options.into_file_build_from_path_options();
let mut pack_builder = pack::Builder::new();
for input_file_path in stdin().lines() {
let input_file_path = PathBuf::from(input_file_path?);
let input_file_error_context = || input_file_path.to_string_lossy().into_owned();
let file_pack_path = file_pack_path::FilePackPath::build_from_path(
&input_file_path,
&input_base_directory_path,
&file_build_from_path_options,
)
.with_context(input_file_error_context)?;
pack_builder
.file_pack_path_add(file_pack_path)
.with_context(|| input_file_path.to_string_lossy().into_owned())?;
}
let pack = pack_builder.finalize();
pack::store_file(&pack, &output_file_path)?;
}
}
Ok(())
}