dev-manager-tauri/src-tauri/src/commands/git_repos.rs
lanrtop 533c069e43 feat: add WSL editor launch modes and update checking functionality
- Introduced WSL editor launch modes in SettingsPage with options for internal, remote, and UNC path launches.
- Enhanced settings saving to include the new WSL launch mode.
- Added an update section to check for application updates, download, and install them with progress tracking.
- Updated Toast component to handle error messages with a copy button for convenience.
- Expanded commands to include project tags and templates management, along with WSL proxy synchronization features.
2026-04-01 23:12:23 +09:00

192 lines
6.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::db::pool;
use crate::models::GitRepo;
use rusqlite::params;
use serde::Deserialize;
// ── 输入结构体 ─────────────────────────────────────────────────────────────────
#[derive(Debug, Deserialize)]
pub struct ImportGitRepoInput {
pub id: String,
pub repo_url: String,
pub name: String,
pub description: Option<String>,
pub default_branch: Option<String>,
pub upstream_url: Option<String>,
pub tech_stack: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct UpdateGitRepoDeployInput {
pub staging_url: Option<String>,
pub prod_url: Option<String>,
pub server_note: Option<String>,
pub upstream_url: Option<String>,
pub tech_stack: Option<String>,
pub status: Option<String>,
pub priority: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct MountRepoInput {
/// 新 workspace 的 id(前端传 UUID)
pub workspace_id: String,
pub repo_id: String,
pub space_id: Option<String>,
pub win_path: Option<String>,
pub wsl_path: Option<String>,
pub platform: Option<String>,
}
// ── 命令实现 ───────────────────────────────────────────────────────────────────
/// 获取所有已注册仓库
#[tauri::command]
pub fn get_git_repos() -> Result<Vec<GitRepo>, String> {
let conn = pool().get().map_err(|e| e.to_string())?;
let mut stmt = conn
.prepare("SELECT * FROM git_repos ORDER BY created_at DESC")
.map_err(|e| e.to_string())?;
let rows = stmt
.query_map([], GitRepo::from_row)
.map_err(|e| e.to_string())?
.collect::<rusqlite::Result<Vec<_>>>()
.map_err(|e| e.to_string())?;
Ok(rows)
}
/// 批量导入 GitHub 仓库(INSERT OR IGNORE,幂等)
#[tauri::command]
pub fn import_git_repos(repos: Vec<ImportGitRepoInput>) -> Result<Vec<String>, String> {
let conn = pool().get().map_err(|e| e.to_string())?;
let mut imported = Vec::new();
for r in repos {
let affected = conn
.execute(
"INSERT OR IGNORE INTO git_repos
(id, repo_url, name, description, default_branch, upstream_url, tech_stack,
last_synced_at)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, datetime('now'))",
params![
r.id,
r.repo_url,
r.name,
r.description,
r.default_branch,
r.upstream_url,
r.tech_stack,
],
)
.map_err(|e| e.to_string())?;
if affected > 0 {
imported.push(r.id);
}
}
Ok(imported)
}
/// 更新仓库部署信息(staging_url, prod_url, server_note, upstream_url 等)
#[tauri::command]
pub fn update_git_repo_deploy(id: String, input: UpdateGitRepoDeployInput) -> Result<(), String> {
let conn = pool().get().map_err(|e| e.to_string())?;
conn.execute(
"UPDATE git_repos SET
staging_url = COALESCE(?2, staging_url),
prod_url = COALESCE(?3, prod_url),
server_note = COALESCE(?4, server_note),
upstream_url = COALESCE(?5, upstream_url),
tech_stack = COALESCE(?6, tech_stack),
status = COALESCE(?7, status),
priority = COALESCE(?8, priority)
WHERE id = ?1",
params![
id,
input.staging_url,
input.prod_url,
input.server_note,
input.upstream_url,
input.tech_stack,
input.status,
input.priority,
],
)
.map_err(|e| e.to_string())?;
Ok(())
}
/// 将仓库挂载到某个空间(创建 workspace + profile)
#[tauri::command]
pub fn mount_repo(input: MountRepoInput) -> Result<(), String> {
let conn = pool().get().map_err(|e| e.to_string())?;
// 读取 git_repo 基础信息
let repo: GitRepo = conn
.query_row(
"SELECT * FROM git_repos WHERE id = ?1",
params![input.repo_id],
GitRepo::from_row,
)
.map_err(|e| format!("仓库不存在: {e}"))?;
let profile_id = format!("prof-{}", input.workspace_id);
// 创建 project_profile(若已存在则忽略)
conn.execute(
"INSERT OR IGNORE INTO project_profiles
(id, name, description, repo_url, upstream_url, default_branch,
staging_url, prod_url, server_note, status, priority, tech_stack)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)",
params![
profile_id,
repo.name,
repo.description,
repo.repo_url,
repo.upstream_url,
repo.default_branch,
repo.staging_url,
repo.prod_url,
repo.server_note,
repo.status.as_deref().unwrap_or("active"),
repo.priority.as_deref().unwrap_or("mid"),
repo.tech_stack,
],
)
.map_err(|e| e.to_string())?;
let platform = input.platform.as_deref().unwrap_or("windows");
// 创建 project_workspace(若同一 space 已挂载则报错)
conn.execute(
"INSERT INTO project_workspaces
(id, profile_id, repo_id, space_id, win_path, wsl_path, platform)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
params![
input.workspace_id,
profile_id,
input.repo_id,
input.space_id,
input.win_path,
input.wsl_path,
platform,
],
)
.map_err(|e| {
if e.to_string().contains("UNIQUE") {
"该仓库已在此空间中挂载".to_string()
} else {
e.to_string()
}
})?;
Ok(())
}
/// 删除仓库注册记录(同时删除关联的 workspace/profile)
#[tauri::command]
pub fn delete_git_repo(id: String) -> Result<(), String> {
let conn = pool().get().map_err(|e| e.to_string())?;
conn.execute("DELETE FROM git_repos WHERE id = ?1", params![id])
.map_err(|e| e.to_string())?;
Ok(())
}