1use crate::config::YamlConfig;
2use crate::constants::{section, shell};
3use crate::{error, info};
4use std::fs;
5
6fn wait_for_key_template() -> String {
8 if std::env::consts::OS == shell::WINDOWS_OS {
9 "echo.\necho 脚本执行完毕,按任意键退出...\npause >nul".to_string()
10 } else {
11 "echo ''\necho '\\033[32m✅ 脚本执行完毕,按回车键退出...\\033[0m'\nread _".to_string()
12 }
13}
14
15pub fn handle_concat(name: &str, content: &[String], config: &mut YamlConfig) {
19 if config.contains(section::PATH, name) {
21 let existing_path = match config
23 .get_property(section::SCRIPT, name)
24 .or_else(|| config.get_property(section::PATH, name))
25 {
26 Some(p) => p.clone(),
27 None => {
28 error!("❌ 别名 {{{}}} 已存在,但未找到对应的脚本路径", name);
29 return;
30 }
31 };
32
33 let existing_content = match fs::read_to_string(&existing_path) {
35 Ok(c) => c,
36 Err(e) => {
37 error!("❌ 读取已有脚本文件失败: {} (路径: {})", e, existing_path);
38 return;
39 }
40 };
41
42 let initial_lines: Vec<String> = existing_content.lines().map(|l| l.to_string()).collect();
44 match crate::tui::editor::open_multiline_editor_with_content(
45 &format!("📝 编辑脚本: {}", name),
46 &initial_lines,
47 ) {
48 Ok(Some(new_content)) => {
49 if new_content.trim().is_empty() {
50 error!("⚠️ 脚本内容为空,未保存修改");
51 return;
52 }
53 match fs::write(&existing_path, &new_content) {
55 Ok(_) => info!("✅ 脚本 {{{}}} 已更新,路径: {}", name, existing_path),
56 Err(e) => error!("💥 写入脚本文件失败: {}", e),
57 }
58 }
59 Ok(None) => {
60 info!("已取消编辑脚本");
61 }
62 Err(e) => {
63 error!("❌ 编辑器启动失败: {}", e);
64 }
65 }
66 return;
67 }
68
69 let script_content = if content.is_empty() {
71 let initial_lines = vec![
73 "#!/bin/bash".to_string(),
74 "".to_string(),
75 "# 在此编写脚本内容...".to_string(),
76 "".to_string(),
77 "# --- 以下为等待按键模板(可删除) ---".to_string(),
78 wait_for_key_template(),
79 ];
80
81 match crate::tui::editor::open_multiline_editor_with_content(
82 &format!("📝 编写脚本: {}", name),
83 &initial_lines,
84 ) {
85 Ok(Some(text)) => text,
86 Ok(None) => {
87 info!("已取消创建脚本");
88 return;
89 }
90 Err(e) => {
91 error!("❌ 编辑器启动失败: {}", e);
92 return;
93 }
94 }
95 } else {
96 let text = content.join(" ");
98 text.trim()
99 .trim_start_matches('"')
100 .trim_end_matches('"')
101 .to_string()
102 };
103
104 if script_content.trim().is_empty() {
105 error!("⚠️ 脚本内容为空,无法创建");
106 return;
107 }
108
109 let scripts_dir = YamlConfig::scripts_dir();
111
112 let ext = if std::env::consts::OS == shell::WINDOWS_OS {
114 ".cmd"
115 } else {
116 ".sh"
117 };
118 let script_path = scripts_dir.join(format!("{}{}", name, ext));
119 let script_path_str = script_path.to_string_lossy().to_string();
120
121 if let Some(parent) = script_path.parent() {
123 if let Err(e) = fs::create_dir_all(parent) {
124 error!("❌ 创建目录失败: {}", e);
125 return;
126 }
127 }
128
129 match fs::write(&script_path, &script_content) {
131 Ok(_) => {
132 info!("🎉 文件创建成功: {}", script_path_str);
133 }
134 Err(e) => {
135 error!("💥 写入脚本文件失败: {}", e);
136 return;
137 }
138 }
139
140 #[cfg(unix)]
142 {
143 use std::os::unix::fs::PermissionsExt;
144 if let Ok(metadata) = fs::metadata(&script_path) {
145 let mut perms = metadata.permissions();
146 perms.set_mode(perms.mode() | 0o111); if let Err(e) = fs::set_permissions(&script_path, perms) {
148 error!("❌ 设置执行权限失败: {}", e);
149 } else {
150 info!("🔧 已为脚本 {{{}}} 设置执行权限", name);
151 }
152 }
153 }
154
155 config.set_property(section::PATH, name, &script_path_str);
157 config.set_property(section::SCRIPT, name, &script_path_str);
158
159 info!("✅ 成功创建脚本 {{{}}},路径: {}", name, script_path_str);
160}