use crate::{
interface::replace_placeholders, macro_generate_from_csv,
macro_generate_from_ini, macro_generate_from_json,
macro_generate_from_toml, macro_generate_from_yaml,
models::model_params::FileGenerationParams,
utils::create_directory,
};
use std::{fs, io, path::PathBuf};
pub fn create_template_folder() -> io::Result<()> {
let current_dir = std::env::current_dir()?;
let template_dir_path = current_dir.join("template");
create_directory(&template_dir_path)?;
let url = "https://raw.githubusercontent.com/sebastienrousseau/libmake/main/template/";
let files = [
"AUTHORS.tpl",
"build.tpl",
"Cargo.tpl",
"ci.tpl",
"CONTRIBUTING.tpl",
"criterion.tpl",
"deepsource.tpl",
"deny.tpl",
"example.tpl",
"gitignore.tpl",
"lib.tpl",
"macros.tpl",
"main.tpl",
"README.tpl",
"rustfmt.tpl",
"TEMPLATE.tpl",
"test.tpl",
];
for file in &files {
let file_path = template_dir_path.join(file);
if !file_path.exists() {
let file_url = format!("{url}{file}");
let response =
reqwest::blocking::get(&file_url).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!(
"Failed to download template file: {e}"
),
)
})?;
let file_contents = response.text().map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("Failed to read response body: {e}"),
)
})?;
fs::write(
&file_path,
file_contents
.trim_start_matches('\n')
.trim_end_matches('\n'),
)?;
}
}
Ok(())
}
#[allow(unused_results)]
pub fn copy_and_replace_template(
template_file: &str,
dest_file: &str,
project_directory: &PathBuf,
params: &FileGenerationParams,
) -> io::Result<()> {
let mut tpl_file = PathBuf::new();
tpl_file.push("template");
tpl_file.push(template_file);
let mut dest_path = PathBuf::new();
dest_path.push(project_directory);
dest_path.push(dest_file);
fs::copy(&tpl_file, &dest_path)?;
replace_placeholders(&tpl_file, &dest_path, params)?;
Ok(())
}
pub fn generate_files(params: FileGenerationParams) -> io::Result<()> {
let Some(ref output) = params.output else {
return Err(io::Error::new(
io::ErrorKind::Other,
"Output directory is not specified",
));
};
let project_directory =
PathBuf::from(output.clone().trim_matches('\"'));
create_directory(&project_directory)?;
create_template_folder()?;
let subdirectories = [
"src",
"benches",
"examples",
"tests",
".github/",
".github/workflows",
];
for subdir in &subdirectories {
let dir_path = project_directory.join(subdir);
create_directory(&dir_path)?;
}
let templates = [
("github/workflows/audit.tpl", ".github/workflows/audit.yml"),
("github/workflows/check.tpl", ".github/workflows/check.yml"),
(
"github/workflows/coverage.tpl",
".github/workflows/coverage.yml",
),
(
"github/workflows/document.tpl",
".github/workflows/document.yml",
),
("github/workflows/lint.tpl", ".github/workflows/lint.yml"),
(
"github/workflows/release.tpl",
".github/workflows/release.yml",
),
("github/workflows/test.tpl", ".github/workflows/test.yml"),
("AUTHORS.tpl", "AUTHORS.md"),
("build.tpl", "build.rs"),
("Cargo.tpl", "Cargo.toml"),
("CONTRIBUTING.tpl", "CONTRIBUTING.md"),
("criterion.tpl", "benches/criterion.rs"),
("deepsource.tpl", ".deepsource.toml"),
("deny.tpl", "deny.toml"),
("example.tpl", "examples/example.rs"),
("gitignore.tpl", ".gitignore"),
("lib.tpl", "src/lib.rs"),
("macros.tpl", "src/macros.rs"),
("main.tpl", "src/main.rs"),
("README.tpl", "README.md"),
("rustfmt.tpl", "rustfmt.toml"),
("TEMPLATE.tpl", "TEMPLATE.md"),
("test_test.tpl", "tests/test_test.rs"),
];
for (template, target) in templates {
copy_and_replace_template(
template,
target,
&project_directory,
¶ms,
)?;
}
println!("{:<15}Value", "Argument");
println!("{:<15}{}", "author", params.author.unwrap_or_default());
println!("{:<15}{}", "build", params.build.unwrap_or_default());
println!(
"{:<15}{}",
"categories",
params.categories.unwrap_or_default()
);
println!(
"{:<15}{}",
"description",
params.description.unwrap_or_default()
);
println!(
"{:<15}{}",
"documentation",
params.documentation.unwrap_or_default()
);
println!("{:<15}{}", "edition", params.edition.unwrap_or_default());
println!("{:<15}{}", "email", params.email.unwrap_or_default());
println!(
"{:<15}{}",
"homepage",
params.homepage.unwrap_or_default()
);
println!(
"{:<15}{}",
"keywords",
params.keywords.unwrap_or_default()
);
println!("{:<15}{}", "license", params.license.unwrap_or_default());
println!("{:<15}{}", "name", params.name.unwrap_or_default());
println!("{:<15}{}", "output", output.clone());
println!("{:<15}{}", "readme", params.readme.unwrap_or_default());
println!(
"{:<15}{}",
"repository",
params.repository.unwrap_or_default()
);
println!(
"{:<15}{}",
"rustversion",
params.rustversion.unwrap_or_default()
);
println!("{:<15}{}", "version", params.version.unwrap_or_default());
println!("{:<15}{}", "website", params.website.unwrap_or_default());
Ok(())
}
pub fn generate_from_config(
path: &str,
file_type: &str,
) -> Result<(), String> {
match file_type {
"csv" => macro_generate_from_csv!(path)?,
"ini" => macro_generate_from_ini!(path)?,
"json" => macro_generate_from_json!(path)?,
"yaml" => macro_generate_from_yaml!(path)?,
"toml" => macro_generate_from_toml!(path)?,
_ => {
return Err(format!(
"Unsupported configuration file type: {}",
file_type
))
}
}
Ok(())
}