@@ -14,6 +14,14 @@ use std::process::Command;
1414use zip:: write:: FileOptions ;
1515use 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+
1725fn 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
85138title Welcome to TechScript!
86139color 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