Fix built-in template rename order
This commit is contained in:
@@ -1,25 +1,20 @@
|
||||
use crate::{
|
||||
config::Config,
|
||||
entity::project::ProjectInfo,
|
||||
template::TemplateEngine,
|
||||
utils::{file, http::HttpClient},
|
||||
commands::CreateArgs, entity::project::ProjectInfo, error::Result, template::TemplateEngine,
|
||||
};
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::commands::CreateArgs;
|
||||
use crate::error::Result;
|
||||
use crate::utils::git;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn execute(args: &CreateArgs, temp_dir: &PathBuf) {
|
||||
if let Err(e) = create_project(&args.name, args.target.as_deref(), temp_dir) {
|
||||
eprintln!("错误: {}", e);
|
||||
include!(concat!(env!("OUT_DIR"), "/embedded_examples.rs"));
|
||||
|
||||
pub fn execute(args: &CreateArgs) {
|
||||
if let Err(e) = create_project(&args.name, args.target.as_deref()) {
|
||||
eprintln!("Error: {}", e);
|
||||
return;
|
||||
}
|
||||
println!("成功: 项目已创建");
|
||||
println!("Success: project created.");
|
||||
}
|
||||
|
||||
fn create_project(name: &str, target: Option<&str>, temp_dir: &PathBuf) -> Result<()> {
|
||||
fn create_project(name: &str, target: Option<&str>) -> Result<()> {
|
||||
let target = target.unwrap_or("default");
|
||||
|
||||
check_example_exists(target)?;
|
||||
@@ -27,30 +22,16 @@ fn create_project(name: &str, target: Option<&str>, temp_dir: &PathBuf) -> Resul
|
||||
let local_dir = PathBuf::from(format!("./{}", name));
|
||||
fs::create_dir(&local_dir)?;
|
||||
|
||||
let template_dir = clone_and_copy_template(target, temp_dir, &local_dir)?;
|
||||
|
||||
initialize_project_with_template(&template_dir, &local_dir, name)?;
|
||||
copy_embedded_template(target, &local_dir)?;
|
||||
initialize_project_with_template(&local_dir, &local_dir, name)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_example_exists(target: &str) -> Result<()> {
|
||||
let check_url = format!(
|
||||
"https://api.github.com/repos/AiYo-Studio/emod-cli/contents/examples/{}",
|
||||
target
|
||||
);
|
||||
|
||||
let client = if cfg!(debug_assertions) {
|
||||
HttpClient::new_with_proxy("http://127.0.0.1:1080")?
|
||||
} else {
|
||||
HttpClient::new()?
|
||||
};
|
||||
|
||||
let resp = client.get(&check_url)?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
if !embedded_example_exists(target) {
|
||||
return Err(crate::error::CliError::NotFound(format!(
|
||||
"示例模板 '{}' 不存在",
|
||||
"example target '{}' was not found in the built-in examples",
|
||||
target
|
||||
)));
|
||||
}
|
||||
@@ -58,21 +39,47 @@ fn check_example_exists(target: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clone_and_copy_template(
|
||||
target: &str,
|
||||
temp_dir: &PathBuf,
|
||||
local_dir: &PathBuf,
|
||||
) -> Result<PathBuf> {
|
||||
let _ = fs::remove_dir_all(format!("{}/tmp", temp_dir.display()));
|
||||
fn embedded_example_exists(target: &str) -> bool {
|
||||
let target = normalize_embedded_path(target);
|
||||
let prefix = format!("{}/", target);
|
||||
|
||||
let config = Config::load();
|
||||
let url = &config.repo_url;
|
||||
git::clone_remote_project(url.to_string(), temp_dir)?;
|
||||
EMBEDDED_EXAMPLE_DIRS
|
||||
.iter()
|
||||
.any(|dir| *dir == target || dir.starts_with(&prefix))
|
||||
|| EMBEDDED_EXAMPLE_FILES
|
||||
.iter()
|
||||
.any(|file| file.path.starts_with(&prefix))
|
||||
}
|
||||
|
||||
let target_dir = PathBuf::from(format!("{}/tmp/examples/{}", temp_dir.display(), target));
|
||||
file::copy_folder(&target_dir, local_dir)?;
|
||||
fn copy_embedded_template(target: &str, local_dir: &PathBuf) -> Result<()> {
|
||||
let target = normalize_embedded_path(target);
|
||||
let prefix = format!("{}/", target);
|
||||
|
||||
Ok(target_dir)
|
||||
for dir in EMBEDDED_EXAMPLE_DIRS {
|
||||
if let Some(relative_path) = dir.strip_prefix(&prefix) {
|
||||
if !relative_path.is_empty() {
|
||||
fs::create_dir_all(local_dir.join(relative_path))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for file in EMBEDDED_EXAMPLE_FILES {
|
||||
let Some(relative_path) = file.path.strip_prefix(&prefix) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let output_path = local_dir.join(relative_path);
|
||||
if let Some(parent) = output_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
fs::write(output_path, file.contents)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn normalize_embedded_path(path: &str) -> String {
|
||||
path.trim_matches(['/', '\\']).replace('\\', "/")
|
||||
}
|
||||
|
||||
fn initialize_project_with_template(
|
||||
@@ -80,14 +87,10 @@ fn initialize_project_with_template(
|
||||
local_dir: &PathBuf,
|
||||
name: &str,
|
||||
) -> Result<()> {
|
||||
let lower_name = format!(
|
||||
"{}{}",
|
||||
name.chars().next().unwrap().to_lowercase(),
|
||||
&name[1..]
|
||||
);
|
||||
let lower_name = lower_first_char(name)?;
|
||||
|
||||
println!("项目名称: {}", name);
|
||||
println!("标识名称: {}", lower_name);
|
||||
println!("Project name: {}", name);
|
||||
println!("Lower project name: {}", lower_name);
|
||||
|
||||
let project_info = generate_project_info(name, &lower_name);
|
||||
|
||||
@@ -124,10 +127,30 @@ fn initialize_project_with_template(
|
||||
);
|
||||
|
||||
engine.process_directory(local_dir)?;
|
||||
remove_template_config(local_dir)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_template_config(local_dir: &PathBuf) -> Result<()> {
|
||||
let template_config = local_dir.join("template.toml");
|
||||
if template_config.exists() {
|
||||
fs::remove_file(template_config)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn lower_first_char(name: &str) -> Result<String> {
|
||||
let mut chars = name.chars();
|
||||
let Some(first) = chars.next() else {
|
||||
return Err(crate::error::CliError::InvalidInput(
|
||||
"project name cannot be empty".to_string(),
|
||||
));
|
||||
};
|
||||
|
||||
Ok(format!("{}{}", first.to_lowercase(), chars.as_str()))
|
||||
}
|
||||
|
||||
fn generate_project_info(name: &str, lower_name: &str) -> ProjectInfo {
|
||||
ProjectInfo {
|
||||
name: name.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user