初始化项目启动器代码
This commit is contained in:
@@ -3,6 +3,7 @@ pub mod conversations;
|
||||
pub mod folder_commands;
|
||||
pub mod folders;
|
||||
pub mod mcp;
|
||||
pub mod project_boot;
|
||||
pub mod system_settings;
|
||||
pub mod terminal;
|
||||
pub mod version_control;
|
||||
|
||||
92
src-tauri/src/commands/project_boot.rs
Normal file
92
src-tauri/src/commands/project_boot.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::app_error::AppCommandError;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn create_shadcn_project(
|
||||
project_name: String,
|
||||
template: String,
|
||||
preset_code: String,
|
||||
package_manager: String,
|
||||
target_dir: String,
|
||||
) -> Result<String, AppCommandError> {
|
||||
let project_name = project_name.trim().to_string();
|
||||
let template = template.trim().to_string();
|
||||
let preset_code = preset_code.trim().to_string();
|
||||
let package_manager = package_manager.trim().to_string();
|
||||
let target_dir = target_dir.trim().to_string();
|
||||
|
||||
if project_name.is_empty() {
|
||||
return Err(AppCommandError::invalid_input("Project name is required"));
|
||||
}
|
||||
if template.is_empty() {
|
||||
return Err(AppCommandError::invalid_input("Template is required"));
|
||||
}
|
||||
if target_dir.is_empty() {
|
||||
return Err(AppCommandError::invalid_input("Target directory is required"));
|
||||
}
|
||||
|
||||
let full_path = PathBuf::from(&target_dir).join(&project_name);
|
||||
let full_path_str = full_path.to_string_lossy().to_string();
|
||||
|
||||
// Check if directory already exists and is non-empty
|
||||
if full_path.exists() {
|
||||
let is_empty = full_path
|
||||
.read_dir()
|
||||
.map(|mut entries| entries.next().is_none())
|
||||
.unwrap_or(false);
|
||||
if !is_empty {
|
||||
return Err(AppCommandError::already_exists(
|
||||
"Target directory already exists and is not empty",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the command based on package manager
|
||||
let (program, prefix_args): (&str, Vec<&str>) = match package_manager.as_str() {
|
||||
"pnpm" => ("pnpm", vec!["dlx"]),
|
||||
"yarn" => ("yarn", vec!["dlx"]),
|
||||
"bun" => ("bunx", vec![]),
|
||||
_ => ("npx", vec![]),
|
||||
};
|
||||
|
||||
let mut cmd = crate::process::tokio_command(program);
|
||||
cmd.args(&prefix_args);
|
||||
cmd.args([
|
||||
"shadcn@latest",
|
||||
"init",
|
||||
"-n",
|
||||
&project_name,
|
||||
"-t",
|
||||
&template,
|
||||
"-p",
|
||||
&preset_code,
|
||||
"-y",
|
||||
]);
|
||||
cmd.current_dir(&target_dir);
|
||||
|
||||
let output = cmd.output().await.map_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
AppCommandError::dependency_missing(format!(
|
||||
"{program} is not installed. Please install Node.js first."
|
||||
))
|
||||
} else {
|
||||
AppCommandError::external_command(
|
||||
"Failed to execute project creation command",
|
||||
e.to_string(),
|
||||
)
|
||||
}
|
||||
})?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
let detail = if stderr.is_empty() { stdout } else { stderr };
|
||||
return Err(AppCommandError::external_command(
|
||||
"Project creation command failed",
|
||||
detail,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(full_path_str)
|
||||
}
|
||||
@@ -604,3 +604,30 @@ pub async fn open_push_window(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn open_project_boot_window(app: AppHandle) -> Result<(), AppCommandError> {
|
||||
if let Some(existing) = app.get_webview_window("project-boot") {
|
||||
ensure_windows_undecorated(&existing);
|
||||
let _ = existing.unminimize();
|
||||
existing.set_focus().map_err(|e| {
|
||||
AppCommandError::window("Failed to focus project boot window", e.to_string())
|
||||
})?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let url = WebviewUrl::App("project-boot".into());
|
||||
let builder = WebviewWindowBuilder::new(&app, "project-boot", url)
|
||||
.title("Project Boot")
|
||||
.inner_size(1400.0, 900.0)
|
||||
.min_inner_size(1100.0, 700.0)
|
||||
.center();
|
||||
let window = apply_platform_window_style(builder)
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
AppCommandError::window("Failed to open project boot window", e.to_string())
|
||||
})?;
|
||||
ensure_windows_undecorated(&window);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user