Skip to content

Commit d6373fb

Browse files
authored
Merge pull request #113 from Tcode-Motion/refactor/packager-main-9736293174791145260
🧹 [Refactor packager main function for readability]
2 parents 868f391 + fda2824 commit d6373fb

1 file changed

Lines changed: 126 additions & 42 deletions

File tree

‎tools/packager/src/main.rs‎

Lines changed: 126 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ use std::process::Command;
1414
use zip::write::FileOptions;
1515
use zip::ZipWriter;
1616

17+
struct ReleaseDirectories {
18+
release_dir: PathBuf,
19+
tools_dir: PathBuf,
20+
runtime_dir: PathBuf,
21+
docs_dir: PathBuf,
22+
examples_dir: PathBuf,
23+
}
24+
1725
fn main() -> anyhow::Result<()> {
1826
println!("=== Starting TechScript 2.0 Packaging Pipeline ===");
1927

@@ -32,13 +40,52 @@ fn main() -> anyhow::Result<()> {
3240
compile_binary(&root_dir, "techscript_lsp")?;
3341

3442
// 4. Create release folder structure
43+
let dirs = setup_release_directories(&root_dir)?;
44+
45+
// 5. Build Tools binaries
46+
build_and_copy_tools(&root_dir, &dirs.tools_dir)?;
47+
48+
// 6-9. Copy resources and generate notes
49+
let (git_commit, build_date) = copy_resources(
50+
&root_dir,
51+
&dirs.runtime_dir,
52+
&dirs.examples_dir,
53+
&dirs.docs_dir,
54+
&dirs.release_dir,
55+
)?;
56+
57+
// 10-17. Package installers, ZIPs, and sign binaries
58+
package_installers(
59+
&root_dir,
60+
&dirs.release_dir,
61+
&version,
62+
&dirs.runtime_dir,
63+
&dirs.examples_dir,
64+
&dirs.docs_dir,
65+
&dirs.tools_dir,
66+
)?;
67+
68+
// 18-20. Generate manifest, checksums, and versioned release folder
69+
finalize_release(
70+
&root_dir,
71+
&dirs.release_dir,
72+
&version,
73+
&git_commit,
74+
&build_date,
75+
&dirs.examples_dir,
76+
&dirs.docs_dir,
77+
)?;
78+
79+
Ok(())
80+
}
81+
82+
fn setup_release_directories(root_dir: &Path) -> anyhow::Result<ReleaseDirectories> {
3583
let release_dir = root_dir.join("releases").join("current");
3684
if release_dir.exists() {
3785
fs::remove_dir_all(&release_dir).context("Failed to clean current release directory")?;
3886
}
3987
fs::create_dir_all(&release_dir)?;
4088

41-
// Target Directories
4289
let tools_dir = release_dir.join("tools");
4390
let runtime_dir = release_dir.join("runtime");
4491
let docs_dir = release_dir.join("docs");
@@ -49,7 +96,16 @@ fn main() -> anyhow::Result<()> {
4996
fs::create_dir_all(&docs_dir)?;
5097
fs::create_dir_all(&examples_dir)?;
5198

52-
// 5. Build Tools binaries
99+
Ok(ReleaseDirectories {
100+
release_dir,
101+
tools_dir,
102+
runtime_dir,
103+
docs_dir,
104+
examples_dir,
105+
})
106+
}
107+
108+
fn build_and_copy_tools(root_dir: &Path, tools_dir: &Path) -> anyhow::Result<()> {
53109
let target_release = root_dir.join("target").join("release");
54110
let tsc_exe = target_release.join("tsc.exe");
55111
let lsp_exe = target_release.join("techscript-lsp.exe");
@@ -64,7 +120,6 @@ fn main() -> anyhow::Result<()> {
64120
));
65121
}
66122

67-
// Copy compiler driver & duplicate to make compiler tool suite
68123
let tools_list = [
69124
"tsc.exe",
70125
"tsvm.exe",
@@ -77,10 +132,8 @@ fn main() -> anyhow::Result<()> {
77132
for tool_name in &tools_list {
78133
fs::copy(&tsc_exe, tools_dir.join(tool_name))?;
79134
}
80-
// Copy LSP as tsls.exe
81135
fs::copy(&lsp_exe, tools_dir.join("tsls.exe"))?;
82136

83-
// Create the First-Run Experience welcome batch file
84137
let welcome_bat_content = r#"@echo off
85138
title Welcome to TechScript!
86139
color 0A
@@ -107,19 +160,28 @@ pause
107160
"#;
108161
fs::write(tools_dir.join("welcome.bat"), welcome_bat_content)?;
109162

110-
// 6. Copy standard library sources to runtime/stdlib
163+
Ok(())
164+
}
165+
166+
fn copy_resources(
167+
root_dir: &Path,
168+
runtime_dir: &Path,
169+
examples_dir: &Path,
170+
docs_dir: &Path,
171+
release_dir: &Path,
172+
) -> anyhow::Result<(String, String)> {
111173
let stdlib_dest = runtime_dir.join("stdlib");
112174
fs::create_dir_all(&stdlib_dest)?;
113175
if root_dir.join("stdlib").exists() {
114176
copy_dir_all(root_dir.join("stdlib"), &stdlib_dest)?;
115177
} else {
116178
fs::write(
117179
stdlib_dest.join("README.md"),
118-
"# Stdlib runtime source placeholder\n",
180+
"# Stdlib runtime source placeholder
181+
",
119182
)?;
120183
}
121184

122-
// 7. Copy flattened examples to examples/ (retaining compat)
123185
if root_dir.join("examples").exists() {
124186
for entry in fs::read_dir(root_dir.join("examples"))? {
125187
let entry = entry?;
@@ -133,7 +195,6 @@ pause
133195
}
134196
}
135197

136-
// 8. Copy specific docs to docs/
137198
let required_docs = [
138199
"LanguageGuide.md",
139200
"SyntaxGuide.md",
@@ -153,12 +214,12 @@ pause
153214
fs::copy(&doc_src, docs_dir.join(doc_name))?;
154215
}
155216
}
156-
// Also copy root README.md to docs/README.md
217+
157218
if root_dir.join("README.md").exists() {
158219
fs::copy(root_dir.join("README.md"), docs_dir.join("README.md"))?;
220+
fs::copy(root_dir.join("README.md"), release_dir.join("README.md"))?;
159221
}
160222

161-
// 9. Copy licenses & metadata to release root
162223
if root_dir.join("LICENSE").exists() {
163224
fs::copy(root_dir.join("LICENSE"), release_dir.join("LICENSE"))?;
164225
}
@@ -168,93 +229,116 @@ pause
168229
release_dir.join("CHANGELOG.md"),
169230
)?;
170231
}
171-
if root_dir.join("README.md").exists() {
172-
fs::copy(root_dir.join("README.md"), release_dir.join("README.md"))?;
173-
}
174232

175-
// Create a release notes file
176233
let git_commit = get_git_commit();
177234
let build_date = Local::now().format("%Y-%m-%d").to_string();
178235
let release_notes_content = format!(
179-
"# TechScript 2.0 Release Notes\n\n- Build Date: {}\n- Git Commit: {}\n- Official froze v2.0.0 Release.\n",
236+
"# TechScript 2.0 Release Notes
237+
238+
- Build Date: {}
239+
- Git Commit: {}
240+
- Official froze v2.0.0 Release.
241+
",
180242
build_date, git_commit
181243
);
182244
fs::write(release_dir.join("RELEASE_NOTES.md"), &release_notes_content)?;
183245
fs::write(docs_dir.join("ReleaseNotes.md"), &release_notes_content)?;
184246

185-
// 10. Package VS Code Extension (vsix)
247+
Ok((git_commit, build_date))
248+
}
249+
250+
fn package_installers(
251+
root_dir: &Path,
252+
release_dir: &Path,
253+
version: &str,
254+
runtime_dir: &Path,
255+
examples_dir: &Path,
256+
docs_dir: &Path,
257+
tools_dir: &Path,
258+
) -> anyhow::Result<()> {
186259
let vsix_dest = release_dir.join("TechScript.vsix");
187-
package_vsix(&root_dir, &vsix_dest, &version)?;
260+
package_vsix(root_dir, &vsix_dest, version)?;
188261

189-
// 11. Create Portable release ZIP (excluding installers/zip themselves)
190262
let portable_zip_dest = release_dir.join("TechScript_Portable.zip");
191263
println!(
192264
"Generating portable release: {}",
193265
portable_zip_dest.display()
194266
);
195-
zip_release_folder(&release_dir, &portable_zip_dest)?;
267+
zip_release_folder(release_dir, &portable_zip_dest)?;
196268

197-
// 12. Create Zip packages for Online Installer download
198269
let installer_res_dir = release_dir.join("installer");
199270
fs::create_dir_all(&installer_res_dir)?;
200271

201-
zip_sub_directory(&runtime_dir, &installer_res_dir.join("stdlib.zip"))?;
202-
zip_sub_directory(&examples_dir, &installer_res_dir.join("examples.zip"))?;
203-
zip_sub_directory(&docs_dir, &installer_res_dir.join("docs.zip"))?;
272+
zip_sub_directory(runtime_dir, &installer_res_dir.join("stdlib.zip"))?;
273+
zip_sub_directory(examples_dir, &installer_res_dir.join("examples.zip"))?;
274+
zip_sub_directory(docs_dir, &installer_res_dir.join("docs.zip"))?;
204275

205-
// 13. Write Inno Setup offline and online script configurations
206276
let offline_iss = installer_res_dir.join("offline_installer.iss");
207277
let online_iss = installer_res_dir.join("online_installer.iss");
208278

209-
generate_offline_inno_script(&offline_iss, &version)?;
210-
generate_online_inno_script(&online_iss, &version)?;
279+
generate_offline_inno_script(&offline_iss, version)?;
280+
generate_online_inno_script(&online_iss, version)?;
211281

212-
// 14. Code-sign all tools/ executables before installer packaging
282+
let tools_list = [
283+
"tsc.exe",
284+
"tsvm.exe",
285+
"tspm.exe",
286+
"tsfmt.exe",
287+
"tslint.exe",
288+
"tsdoc.exe",
289+
"tsmigrate.exe",
290+
];
213291
for tool_name in &tools_list {
214292
sign_executable(&tools_dir.join(tool_name));
215293
}
216294
sign_executable(&tools_dir.join("tsls.exe"));
217295

218-
// 15. Compile Offline installer using Inno Setup and copy to online filename so both are same
219296
compile_inno_installer(&offline_iss, &release_dir.join("TechScript_Setup.exe"))?;
220297
fs::copy(
221298
release_dir.join("TechScript_Setup.exe"),
222299
release_dir.join("TechScript_Online_Setup.exe"),
223300
)?;
224301

225-
// 16. Code-sign the setup installers
226302
sign_executable(&release_dir.join("TechScript_Setup.exe"));
227303
sign_executable(&release_dir.join("TechScript_Online_Setup.exe"));
228304

229-
// 17. Clean up installer zip components to keep releases folder clean
230305
let _ = fs::remove_dir_all(&installer_res_dir);
231306

232-
// 18. Generate manifest.json (Release Manifest)
233-
let examples_count = count_files(&examples_dir, "*.txs")?;
234-
let docs_count = count_files(&docs_dir, "*.md")?;
307+
Ok(())
308+
}
309+
310+
fn finalize_release(
311+
root_dir: &Path,
312+
release_dir: &Path,
313+
version: &str,
314+
git_commit: &str,
315+
build_date: &str,
316+
examples_dir: &Path,
317+
docs_dir: &Path,
318+
) -> anyhow::Result<()> {
319+
let examples_count = count_files(examples_dir, "*.txs")?;
320+
let docs_count = count_files(docs_dir, "*.md")?;
235321
let manifest_dest = release_dir.join("manifest.json");
236322

237-
let checksum_json = calculate_checksums_json(&release_dir)?;
323+
let checksum_json = calculate_checksums_json(release_dir)?;
238324
generate_release_manifest(
239325
&manifest_dest,
240-
&version,
241-
&git_commit,
242-
&build_date,
326+
version,
327+
git_commit,
328+
build_date,
243329
examples_count,
244330
docs_count,
245331
&checksum_json,
246332
)?;
247333

248-
// 19. Generate SHA256SUMS.txt
249-
generate_checksums_txt(&release_dir)?;
334+
generate_checksums_txt(release_dir)?;
250335

251-
// 20. Versioned Releases Folder (v2.0.0)
252336
let versioned_dir = root_dir.join("releases").join(format!("v{}", version));
253337
if versioned_dir.exists() {
254338
fs::remove_dir_all(&versioned_dir)?;
255339
}
256340
fs::create_dir_all(&versioned_dir)?;
257-
copy_dir_all(&release_dir, &versioned_dir)?;
341+
copy_dir_all(release_dir, &versioned_dir)?;
258342

259343
println!("=== Packaging Complete! ===");
260344
Ok(())

0 commit comments

Comments
 (0)