@turri-dev/cli 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/.pi/themes/turri-dark.json +80 -0
  2. package/.pi/themes/turri-light.json +82 -0
  3. package/LICENSE +21 -0
  4. package/README.md +272 -2
  5. package/assets/jellyfish/dark-00.png +0 -0
  6. package/assets/jellyfish/dark-01.png +0 -0
  7. package/assets/jellyfish/dark-02.png +0 -0
  8. package/assets/jellyfish/dark-03.png +0 -0
  9. package/assets/jellyfish/dark-04.png +0 -0
  10. package/assets/jellyfish/dark-05.png +0 -0
  11. package/assets/jellyfish/dark-06.png +0 -0
  12. package/assets/jellyfish/dark-07.png +0 -0
  13. package/assets/jellyfish/dark-08.png +0 -0
  14. package/assets/jellyfish/dark-09.png +0 -0
  15. package/assets/jellyfish/dark-10.png +0 -0
  16. package/assets/jellyfish/dark-11.png +0 -0
  17. package/assets/jellyfish/dark-12.png +0 -0
  18. package/assets/jellyfish/dark-13.png +0 -0
  19. package/assets/jellyfish/dark-14.png +0 -0
  20. package/assets/jellyfish/fallback.txt +252 -0
  21. package/assets/jellyfish/light-00.png +0 -0
  22. package/assets/jellyfish/light-01.png +0 -0
  23. package/assets/jellyfish/light-02.png +0 -0
  24. package/assets/jellyfish/light-03.png +0 -0
  25. package/assets/jellyfish/light-04.png +0 -0
  26. package/assets/jellyfish/light-05.png +0 -0
  27. package/assets/jellyfish/light-06.png +0 -0
  28. package/assets/jellyfish/light-07.png +0 -0
  29. package/assets/jellyfish/light-08.png +0 -0
  30. package/assets/jellyfish/light-09.png +0 -0
  31. package/assets/jellyfish/light-10.png +0 -0
  32. package/assets/jellyfish/light-11.png +0 -0
  33. package/assets/jellyfish/light-12.png +0 -0
  34. package/assets/jellyfish/light-13.png +0 -0
  35. package/assets/jellyfish/light-14.png +0 -0
  36. package/bin/turri.mjs +29 -0
  37. package/dist/ask.js +149 -0
  38. package/dist/brand.js +50 -0
  39. package/dist/btw.js +174 -0
  40. package/dist/chat-models.js +37 -0
  41. package/dist/chat-skills.js +18 -0
  42. package/dist/cli.js +178 -0
  43. package/dist/config-command.js +197 -0
  44. package/dist/config-edit.js +367 -0
  45. package/dist/config.js +489 -0
  46. package/dist/conform-cli.js +29 -0
  47. package/dist/cultivate-cli.js +110 -0
  48. package/dist/drift-cli.js +25 -0
  49. package/dist/environment.js +70 -0
  50. package/dist/extension.js +2372 -0
  51. package/dist/genome.js +301 -0
  52. package/dist/graph.js +246 -0
  53. package/dist/identity.js +35 -0
  54. package/dist/init-config.js +511 -0
  55. package/dist/judge.js +62 -0
  56. package/dist/lineage-cli.js +13 -0
  57. package/dist/loop-cli.js +132 -0
  58. package/dist/loop-tools.js +225 -0
  59. package/dist/mature-tools.js +193 -0
  60. package/dist/model-check.js +117 -0
  61. package/dist/module-report.js +9 -0
  62. package/dist/pi-launch.js +31 -0
  63. package/dist/pi.js +813 -0
  64. package/dist/plain/check.js +76 -0
  65. package/dist/plain/concepts.js +213 -0
  66. package/dist/plain/errors.js +43 -0
  67. package/dist/plain/files.js +57 -0
  68. package/dist/plain/highlight.js +195 -0
  69. package/dist/plain/index.js +15 -0
  70. package/dist/plain/liquid.js +129 -0
  71. package/dist/plain/markdown.js +208 -0
  72. package/dist/plain/parser.js +752 -0
  73. package/dist/plain/plain.tmLanguage.json +124 -0
  74. package/dist/plain/spec.js +291 -0
  75. package/dist/plain/stdlib.js +44 -0
  76. package/dist/question-dialog.js +125 -0
  77. package/dist/questioning.js +109 -0
  78. package/dist/quiet.js +125 -0
  79. package/dist/regenerate/activity.js +187 -0
  80. package/dist/regenerate/agent-env.js +190 -0
  81. package/dist/regenerate/agent-shell.js +114 -0
  82. package/dist/regenerate/arbiter.js +133 -0
  83. package/dist/regenerate/audit.js +203 -0
  84. package/dist/regenerate/cases.js +83 -0
  85. package/dist/regenerate/change-view.js +102 -0
  86. package/dist/regenerate/choose-conformance.js +117 -0
  87. package/dist/regenerate/chunk-plan.js +625 -0
  88. package/dist/regenerate/codebase.js +75 -0
  89. package/dist/regenerate/command-check.js +312 -0
  90. package/dist/regenerate/compaction.js +20 -0
  91. package/dist/regenerate/confine.js +310 -0
  92. package/dist/regenerate/conform.js +133 -0
  93. package/dist/regenerate/conformance-agents.js +955 -0
  94. package/dist/regenerate/conformance.js +936 -0
  95. package/dist/regenerate/conversation-writes.js +100 -0
  96. package/dist/regenerate/credentials.js +88 -0
  97. package/dist/regenerate/debug-log.js +228 -0
  98. package/dist/regenerate/debugger.js +90 -0
  99. package/dist/regenerate/delivery.js +19 -0
  100. package/dist/regenerate/diagnose-job.js +40 -0
  101. package/dist/regenerate/diagnose.js +81 -0
  102. package/dist/regenerate/diff-view.js +240 -0
  103. package/dist/regenerate/drift.js +194 -0
  104. package/dist/regenerate/engine.js +118 -0
  105. package/dist/regenerate/environment-error.js +220 -0
  106. package/dist/regenerate/job-log.js +102 -0
  107. package/dist/regenerate/job-panel.js +336 -0
  108. package/dist/regenerate/jobs-tree.js +300 -0
  109. package/dist/regenerate/jobs.js +427 -0
  110. package/dist/regenerate/lanes.js +32 -0
  111. package/dist/regenerate/lineage.js +384 -0
  112. package/dist/regenerate/loop.js +1435 -0
  113. package/dist/regenerate/masking.js +95 -0
  114. package/dist/regenerate/notes.js +397 -0
  115. package/dist/regenerate/os-sandbox.js +243 -0
  116. package/dist/regenerate/paths.js +165 -0
  117. package/dist/regenerate/plain-palette.js +83 -0
  118. package/dist/regenerate/prompt.js +704 -0
  119. package/dist/regenerate/records.js +294 -0
  120. package/dist/regenerate/regenerate.js +598 -0
  121. package/dist/regenerate/regression.js +181 -0
  122. package/dist/regenerate/release.js +262 -0
  123. package/dist/regenerate/requires.js +241 -0
  124. package/dist/regenerate/resources.js +164 -0
  125. package/dist/regenerate/self-check.js +111 -0
  126. package/dist/regenerate/services.js +155 -0
  127. package/dist/regenerate/shell.js +319 -0
  128. package/dist/regenerate/side-panel.js +278 -0
  129. package/dist/regenerate/spec-map-view.js +574 -0
  130. package/dist/regenerate/spec-map.js +561 -0
  131. package/dist/regenerate/spec-steps.js +527 -0
  132. package/dist/regenerate/state.js +10 -0
  133. package/dist/regenerate/steer.js +91 -0
  134. package/dist/regenerate/steering.js +119 -0
  135. package/dist/regenerate/stop-report.js +161 -0
  136. package/dist/regenerate/submit-work.js +71 -0
  137. package/dist/regenerate/test-kinds.js +124 -0
  138. package/dist/regenerate/test-scripts.js +695 -0
  139. package/dist/regenerate/testing.js +406 -0
  140. package/dist/regenerate/transcript-view.js +1 -0
  141. package/dist/regenerate/unit-gate.js +20 -0
  142. package/dist/regenerate/unit-review.js +347 -0
  143. package/dist/regenerate/web.js +256 -0
  144. package/dist/regenerate/workspace.js +99 -0
  145. package/dist/regenerate-cli.js +68 -0
  146. package/dist/release-agent.js +114 -0
  147. package/dist/release-cli.js +131 -0
  148. package/dist/release-tools.js +148 -0
  149. package/dist/review/live.js +165 -0
  150. package/dist/rules.js +47 -0
  151. package/dist/self-invocation.js +110 -0
  152. package/dist/setup.js +245 -0
  153. package/dist/skill-progress.js +78 -0
  154. package/dist/skill.js +149 -0
  155. package/dist/skills.js +74 -0
  156. package/dist/spec-diff-cli.js +37 -0
  157. package/dist/spec-tools.js +155 -0
  158. package/dist/stack.js +158 -0
  159. package/dist/stacks.js +97 -0
  160. package/dist/stdlib.js +100 -0
  161. package/dist/terminal-images.js +46 -0
  162. package/dist/tools.js +242 -0
  163. package/dist/validate-cli.js +52 -0
  164. package/docs/README.md +58 -0
  165. package/docs/authoring-plain.md +245 -0
  166. package/docs/config.md +353 -0
  167. package/docs/deploy.md +109 -0
  168. package/docs/development.md +75 -0
  169. package/docs/headless.md +148 -0
  170. package/docs/images/how-turri-works.svg +50 -0
  171. package/docs/images/turri-banner.png +0 -0
  172. package/docs/installation.md +118 -0
  173. package/docs/parser.md +108 -0
  174. package/docs/regenerating.md +1116 -0
  175. package/docs/sandbox.md +233 -0
  176. package/docs/skills-and-gates.md +254 -0
  177. package/docs/theming.md +76 -0
  178. package/docs/using.md +454 -0
  179. package/genome/rules/bullet-continuation.md +69 -0
  180. package/genome/rules/concise-specs-examples.md +431 -0
  181. package/genome/rules/concise-specs-integration-examples.md +270 -0
  182. package/genome/rules/concise-specs.md +80 -0
  183. package/genome/rules/definitions.md +107 -0
  184. package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +163 -0
  185. package/genome/rules/examples/integration-embedded-testing/run_unittests_java.sh +51 -0
  186. package/genome/rules/exported-concepts.md +39 -0
  187. package/genome/rules/func-specs.md +129 -0
  188. package/genome/rules/impl-reqs.md +68 -0
  189. package/genome/rules/import-modules.md +48 -0
  190. package/genome/rules/integration-embedded-testing.md +276 -0
  191. package/genome/rules/integration-embedded.md +171 -0
  192. package/genome/rules/integration-standalone.md +135 -0
  193. package/genome/rules/integrations.md +137 -0
  194. package/genome/rules/linked-resources.md +69 -0
  195. package/genome/rules/module-structure.md +105 -0
  196. package/genome/rules/project-model.md +88 -0
  197. package/genome/rules/required-concepts.md +44 -0
  198. package/genome/rules/requires-modules.md +80 -0
  199. package/genome/rules/stdlib.md +73 -0
  200. package/genome/rules/test-reqs.md +57 -0
  201. package/genome/skills/add-acceptance-test/SKILL.md +100 -0
  202. package/genome/skills/add-concept/SKILL.md +71 -0
  203. package/genome/skills/add-functional-spec/SKILL.md +84 -0
  204. package/genome/skills/add-functional-specs/SKILL.md +118 -0
  205. package/genome/skills/add-implementation-requirement/SKILL.md +86 -0
  206. package/genome/skills/add-resource/SKILL.md +105 -0
  207. package/genome/skills/add-template/SKILL.md +64 -0
  208. package/genome/skills/add-test-requirement/SKILL.md +73 -0
  209. package/genome/skills/analyze-2-func-specs/SKILL.md +101 -0
  210. package/genome/skills/analyze-func-specs/SKILL.md +123 -0
  211. package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +211 -0
  212. package/genome/skills/break-down-func-spec/SKILL.md +205 -0
  213. package/genome/skills/brood/SKILL.md +229 -0
  214. package/genome/skills/brood/references/intent.md +35 -0
  215. package/genome/skills/brood/references/product.md +101 -0
  216. package/genome/skills/brood/references/stack.md +61 -0
  217. package/genome/skills/brood/references/testing.md +56 -0
  218. package/genome/skills/bud/SKILL.md +148 -0
  219. package/genome/skills/bud/references/checklist.md +44 -0
  220. package/genome/skills/bud/references/intent.md +30 -0
  221. package/genome/skills/check-plain-env/SKILL.md +285 -0
  222. package/genome/skills/consolidate-concepts/SKILL.md +192 -0
  223. package/genome/skills/create-import-module/SKILL.md +104 -0
  224. package/genome/skills/create-requires-module/SKILL.md +109 -0
  225. package/genome/skills/debug-specs/SKILL.md +188 -0
  226. package/genome/skills/implement-conformance-testing-script/SKILL.md +238 -0
  227. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +337 -0
  228. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +111 -0
  229. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +136 -0
  230. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +103 -0
  231. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +150 -0
  232. package/genome/skills/implement-unit-testing-script/SKILL.md +160 -0
  233. package/genome/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +87 -0
  234. package/genome/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +73 -0
  235. package/genome/skills/implement-unit-testing-script/assets/run_unittests_java.sh +72 -0
  236. package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +81 -0
  237. package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.sh +98 -0
  238. package/genome/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +87 -0
  239. package/genome/skills/init-plain-project/SKILL.md +117 -0
  240. package/genome/skills/init-plain-project/references/checklist.md +30 -0
  241. package/genome/skills/mature/SKILL.md +126 -0
  242. package/genome/skills/refactor-module/SKILL.md +196 -0
  243. package/genome/skills/resolve-section-ownership/SKILL.md +64 -0
  244. package/genome/skills/resolve-spec-conflict/SKILL.md +96 -0
  245. package/genome/skills/spawn/SKILL.md +163 -0
  246. package/package.json +68 -4
  247. package/stdlib/backend/common.plain +25 -0
  248. package/stdlib/backend/conformance/common.plain +12 -0
  249. package/stdlib/backend/conformance/go-gin.plain +9 -0
  250. package/stdlib/backend/conformance/go-nethttp.plain +9 -0
  251. package/stdlib/backend/conformance/java-springboot.plain +9 -0
  252. package/stdlib/backend/conformance/python-django.plain +9 -0
  253. package/stdlib/backend/conformance/python-fastapi.plain +9 -0
  254. package/stdlib/backend/conformance/python-flask.plain +9 -0
  255. package/stdlib/backend/conformance/rust-axum.plain +9 -0
  256. package/stdlib/backend/conformance/typescript-express.plain +9 -0
  257. package/stdlib/backend/conformance/typescript-fastify.plain +9 -0
  258. package/stdlib/backend/conformance/typescript-nestjs.plain +9 -0
  259. package/stdlib/backend/go-gin.plain +18 -0
  260. package/stdlib/backend/go-nethttp.plain +18 -0
  261. package/stdlib/backend/java-springboot.plain +19 -0
  262. package/stdlib/backend/python-django.plain +19 -0
  263. package/stdlib/backend/python-fastapi.plain +23 -0
  264. package/stdlib/backend/python-flask.plain +23 -0
  265. package/stdlib/backend/rust-axum.plain +17 -0
  266. package/stdlib/backend/typescript-express.plain +19 -0
  267. package/stdlib/backend/typescript-fastify.plain +19 -0
  268. package/stdlib/backend/typescript-nestjs.plain +19 -0
  269. package/stdlib/cli/common.plain +17 -0
  270. package/stdlib/cli/conformance/common.plain +11 -0
  271. package/stdlib/cli/conformance/go-cobra.plain +9 -0
  272. package/stdlib/cli/conformance/go-flag.plain +9 -0
  273. package/stdlib/cli/conformance/java-picocli.plain +9 -0
  274. package/stdlib/cli/conformance/python-argparse.plain +9 -0
  275. package/stdlib/cli/conformance/python-click.plain +9 -0
  276. package/stdlib/cli/conformance/python-typer.plain +9 -0
  277. package/stdlib/cli/conformance/rust-clap.plain +9 -0
  278. package/stdlib/cli/conformance/typescript-commander.plain +9 -0
  279. package/stdlib/cli/go-cobra.plain +14 -0
  280. package/stdlib/cli/go-flag.plain +14 -0
  281. package/stdlib/cli/java-picocli.plain +15 -0
  282. package/stdlib/cli/python-argparse.plain +18 -0
  283. package/stdlib/cli/python-click.plain +16 -0
  284. package/stdlib/cli/python-typer.plain +16 -0
  285. package/stdlib/cli/rust-clap.plain +14 -0
  286. package/stdlib/cli/typescript-commander.plain +17 -0
  287. package/stdlib/frontend/angular.plain +17 -0
  288. package/stdlib/frontend/common.plain +17 -0
  289. package/stdlib/frontend/conformance/angular.plain +5 -0
  290. package/stdlib/frontend/conformance/common.plain +11 -0
  291. package/stdlib/frontend/conformance/react-vite.plain +5 -0
  292. package/stdlib/frontend/conformance/sveltekit-spa.plain +5 -0
  293. package/stdlib/frontend/conformance/vue-vite.plain +5 -0
  294. package/stdlib/frontend/react-vite.plain +16 -0
  295. package/stdlib/frontend/sveltekit-spa.plain +16 -0
  296. package/stdlib/frontend/vue-vite.plain +16 -0
  297. package/stdlib/lang/go.plain +13 -0
  298. package/stdlib/lang/java.plain +12 -0
  299. package/stdlib/lang/python.plain +18 -0
  300. package/stdlib/lang/rust.plain +12 -0
  301. package/stdlib/lang/typescript.plain +13 -0
  302. package/stdlib/library/common.plain +15 -0
  303. package/stdlib/library/conformance/common.plain +9 -0
  304. package/stdlib/library/conformance/go.plain +9 -0
  305. package/stdlib/library/conformance/java-gradle.plain +9 -0
  306. package/stdlib/library/conformance/java-maven.plain +9 -0
  307. package/stdlib/library/conformance/python.plain +9 -0
  308. package/stdlib/library/conformance/rust.plain +9 -0
  309. package/stdlib/library/conformance/typescript.plain +9 -0
  310. package/stdlib/library/go.plain +12 -0
  311. package/stdlib/library/java-gradle.plain +13 -0
  312. package/stdlib/library/java-maven.plain +13 -0
  313. package/stdlib/library/python.plain +13 -0
  314. package/stdlib/library/rust.plain +12 -0
  315. package/stdlib/library/typescript.plain +15 -0
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env pwsh
2
+
3
+ $ErrorActionPreference = 'Stop'
4
+
5
+ $UNRECOVERABLE_ERROR_EXIT_CODE = 69
6
+
7
+ $NPM_INSTALL_OUTPUT_FILTER = "up to date in|added [0-9]* packages, removed [0-9]* packages, and changed [0-9]* packages in|removed [0-9]* packages, and changed [0-9]* packages in|added [0-9]* packages in|removed [0-9]* packages in"
8
+
9
+ # Function to check and kill any Node process running on port 3000 (React development server)
10
+ function Check-AndKillNodeServer {
11
+ try {
12
+ $connections = Get-NetTCPConnection -LocalPort 3000 -ErrorAction SilentlyContinue
13
+ if ($connections) {
14
+ foreach ($conn in $connections) {
15
+ $proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
16
+ if ($proc -and $proc.ProcessName -eq "node") {
17
+ Write-Host "Found Node server running on port 3000. Killing it..."
18
+ Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
19
+ Start-Sleep -Seconds 1
20
+ if ($env:VERBOSE -eq "1") {
21
+ Write-Host "Node server terminated."
22
+ }
23
+ }
24
+ }
25
+ }
26
+ } catch {
27
+ # Silently ignore errors (port may not be in use)
28
+ }
29
+ }
30
+
31
+ # Function to get all child processes of a given PID recursively
32
+ function Get-ChildProcesses {
33
+ param([int]$ParentPid)
34
+
35
+ $children = Get-CimInstance Win32_Process -Filter "ParentProcessId = $ParentPid" -ErrorAction SilentlyContinue
36
+ $result = @()
37
+ foreach ($child in $children) {
38
+ $result += $child.ProcessId
39
+ $result += Get-ChildProcesses -ParentPid $child.ProcessId
40
+ }
41
+ return $result
42
+ }
43
+
44
+ # Cleanup function to ensure all processes are terminated
45
+ function Cleanup {
46
+ # Kill any running npm processes started by this script
47
+ if ($script:NPM_PID) {
48
+ Stop-Process -Id $script:NPM_PID -Force -ErrorAction SilentlyContinue
49
+ }
50
+
51
+ # Kill React app and its children if they exist
52
+ if ($script:REACT_APP_PID) {
53
+ $processesToKill = Get-ChildProcesses -ParentPid $script:REACT_APP_PID
54
+
55
+ # Kill the main process
56
+ Stop-Process -Id $script:REACT_APP_PID -Force -ErrorAction SilentlyContinue
57
+
58
+ # Kill all the subprocesses
59
+ foreach ($pid in $processesToKill) {
60
+ Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
61
+ }
62
+
63
+ if ($env:VERBOSE -eq "1") {
64
+ Write-Host "React app is terminated!"
65
+ }
66
+ }
67
+
68
+ # Remove temporary files if they exist
69
+ if ($script:build_output -and (Test-Path $script:build_output)) {
70
+ Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
71
+ }
72
+
73
+ # Step out of any temp subfolder we may still be in before deleting it
74
+ Set-Location -Path ([System.IO.Path]::GetTempPath()) -ErrorAction SilentlyContinue
75
+
76
+ # Remove temporary build subfolders if they exist
77
+ if ($script:NODE_SUBFOLDER -and (Test-Path $script:NODE_SUBFOLDER)) {
78
+ Remove-Item -Path $script:NODE_SUBFOLDER -Recurse -Force -ErrorAction SilentlyContinue
79
+ }
80
+ if ($script:NODE_CONFORMANCE_TESTS_SUBFOLDER -and (Test-Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER)) {
81
+ Remove-Item -Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER -Recurse -Force -ErrorAction SilentlyContinue
82
+ }
83
+ }
84
+
85
+ # Check for and kill any existing Node server from previous runs
86
+ Check-AndKillNodeServer
87
+
88
+ # Check if build folder name is provided
89
+ if (-not $args[0]) {
90
+ Write-Host "Error: No build folder name provided."
91
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
92
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
93
+ }
94
+
95
+ # Check if conformance tests folder name is provided
96
+ if (-not $args[1]) {
97
+ Write-Host "Error: No conformance tests folder name provided."
98
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
99
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
100
+ }
101
+
102
+ $BuildFolder = $args[0]
103
+ $ConformanceTestsFolder = $args[1]
104
+
105
+ if ($args[2] -eq "-v" -or $args[2] -eq "--verbose") {
106
+ $env:VERBOSE = "1"
107
+ }
108
+
109
+ $current_dir = Get-Location
110
+
111
+ try {
112
+ # Define the path to the subfolder. It lives in the system temp directory;
113
+ # $BuildFolder may be an absolute path, so only its leaf name is used.
114
+ $script:NODE_SUBFOLDER = Join-Path ([System.IO.Path]::GetTempPath()) "node_$(Split-Path $BuildFolder -Leaf)"
115
+
116
+ # Running React application
117
+ Write-Host "### Step 1: Starting the React application in folder $script:NODE_SUBFOLDER..."
118
+
119
+ if ($env:VERBOSE -eq "1") {
120
+ Write-Host "Preparing Node subfolder: $script:NODE_SUBFOLDER"
121
+ }
122
+
123
+ # Check if the node subfolder exists
124
+ if (Test-Path $script:NODE_SUBFOLDER) {
125
+ # Delete all files and folders except "node_modules", "plain_modules", and "package-lock.json"
126
+ Get-ChildItem -Path $script:NODE_SUBFOLDER -Force |
127
+ Where-Object {
128
+ $_.Name -ne "node_modules" -and
129
+ $_.Name -ne "plain_modules" -and
130
+ $_.Name -ne "package-lock.json"
131
+ } | Remove-Item -Recurse -Force
132
+
133
+ if ($env:VERBOSE -eq "1") {
134
+ Write-Host "Cleanup completed, keeping 'node_modules' and 'package-lock.json'."
135
+ }
136
+ } else {
137
+ if ($env:VERBOSE -eq "1") {
138
+ Write-Host "Subfolder does not exist. Creating it..."
139
+ }
140
+
141
+ New-Item -ItemType Directory -Path $script:NODE_SUBFOLDER -Force | Out-Null
142
+ }
143
+
144
+ Copy-Item -Path "$BuildFolder/*" -Destination $script:NODE_SUBFOLDER -Recurse -Force
145
+
146
+ # Move to the subfolder
147
+ if (-not (Test-Path $script:NODE_SUBFOLDER)) {
148
+ Write-Host "Error: Node build folder '$script:NODE_SUBFOLDER' does not exist."
149
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
150
+ }
151
+
152
+ Push-Location $script:NODE_SUBFOLDER
153
+
154
+ # Temporarily allow stderr output without throwing (npm may write warnings to stderr)
155
+ # ForEach-Object converts ErrorRecord objects (from stderr) to plain strings to avoid verbose error formatting
156
+ $ErrorActionPreference = 'Continue'
157
+ $npmInstallOutput = npm install --prefer-offline --no-audit --no-fund --loglevel error 2>&1 | ForEach-Object { if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } } | Out-String
158
+ $ErrorActionPreference = 'Stop'
159
+ # Filter out noisy npm install lines
160
+ $npmInstallOutput -split "`n" | Where-Object { $_ -notmatch $NPM_INSTALL_OUTPUT_FILTER } | ForEach-Object {
161
+ if ($_.Trim()) { Write-Host $_ }
162
+ }
163
+
164
+ if ($LASTEXITCODE -ne 0) {
165
+ Write-Host "Error: Installing Node modules."
166
+ exit 2
167
+ }
168
+
169
+ if ($env:VERBOSE -eq "1") {
170
+ Write-Host "Building the application..."
171
+ }
172
+
173
+ $script:build_output = [System.IO.Path]::GetTempFileName()
174
+
175
+ # Temporarily allow stderr output without throwing (build tools may write to stderr)
176
+ $ErrorActionPreference = 'Continue'
177
+ npm run build > $script:build_output 2>&1
178
+ $ErrorActionPreference = 'Stop'
179
+
180
+ if ($LASTEXITCODE -ne 0) {
181
+ Write-Host "Error: Building application."
182
+ Get-Content $script:build_output
183
+ Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
184
+ exit 2
185
+ }
186
+
187
+ Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
188
+
189
+ if ($env:VERBOSE -eq "1") {
190
+ Write-Host "Starting the application..."
191
+ }
192
+
193
+ # Start the React app in the background and redirect output to a log file
194
+ $env:BROWSER = "none"
195
+ $reactProcess = Start-Process -FilePath "npm" -ArgumentList "start", "--", "--no-open" `
196
+ -NoNewWindow -PassThru -RedirectStandardOutput "app.log" -RedirectStandardError "app_err.log"
197
+
198
+ if ($env:VERBOSE -eq "1") {
199
+ Write-Host "Application is starting..."
200
+ }
201
+
202
+ # Capture the process ID
203
+ $script:REACT_APP_PID = $reactProcess.Id
204
+
205
+ # Try to find the child npm process
206
+ Start-Sleep -Milliseconds 500
207
+ $npmChild = Get-CimInstance Win32_Process -Filter "ParentProcessId = $($script:REACT_APP_PID)" -ErrorAction SilentlyContinue |
208
+ Where-Object { $_.Name -match "npm" } | Select-Object -First 1
209
+ if ($npmChild) {
210
+ $script:NPM_PID = $npmChild.ProcessId
211
+ }
212
+
213
+ # Wait for the "compiled successfully!" or Vite ready message in the log file
214
+ while ($true) {
215
+ if (Test-Path "app.log") {
216
+ $logContent = Get-Content "app.log" -Raw -ErrorAction SilentlyContinue
217
+ if ($logContent) {
218
+ if ($logContent -match "(?i)compiled successfully|compiled with warnings") {
219
+ break
220
+ }
221
+ if ($logContent -match "(?i)VITE v[0-9]+\.[0-9]+\.[0-9]+\s+ready in") {
222
+ break
223
+ }
224
+ }
225
+ }
226
+
227
+ # Also check if localhost:3000 responds
228
+ try {
229
+ $response = Invoke-WebRequest -Uri "http://localhost:3000" -UseBasicParsing -TimeoutSec 1 -ErrorAction SilentlyContinue
230
+ if ($response) { break }
231
+ } catch {
232
+ # Not ready yet
233
+ }
234
+
235
+ # Check if the React app process is still running
236
+ $proc = Get-Process -Id $script:REACT_APP_PID -ErrorAction SilentlyContinue
237
+ if (-not $proc -or $proc.HasExited) {
238
+ Write-Host "Error in :ImplementationCode: (React app process (PID: $($script:REACT_APP_PID)) has terminated unexpectedly)."
239
+ if (Test-Path "app.log") { Get-Content "app.log" }
240
+ if (Test-Path "app_err.log") { Get-Content "app_err.log" }
241
+ exit 2
242
+ }
243
+
244
+ Start-Sleep -Milliseconds 100
245
+ }
246
+
247
+ # At this point, the React app is up and running in the background
248
+ if ($env:VERBOSE -eq "1") {
249
+ Write-Host "React app is up and running!"
250
+ }
251
+
252
+ Pop-Location
253
+
254
+ # Execute all Cypress conformance tests in the build folder
255
+ Write-Host "### Step 2: Running Cypress conformance tests $ConformanceTestsFolder..."
256
+
257
+ # Move back to the original directory
258
+ Set-Location $current_dir
259
+
260
+ # Define the path to the conformance tests subfolder. It lives in the system
261
+ # temp directory; $ConformanceTestsFolder may be absolute, so only its leaf name is used.
262
+ $script:NODE_CONFORMANCE_TESTS_SUBFOLDER = Join-Path ([System.IO.Path]::GetTempPath()) "node_$(Split-Path $ConformanceTestsFolder -Leaf)"
263
+
264
+ if ($env:VERBOSE -eq "1") {
265
+ Write-Host "Preparing conformance tests Node subfolder: $script:NODE_CONFORMANCE_TESTS_SUBFOLDER"
266
+ }
267
+
268
+ # Check if the conformance tests node subfolder exists
269
+ if (Test-Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER) {
270
+ # Delete all files and folders except "node_modules", "plain_modules", and "package-lock.json"
271
+ Get-ChildItem -Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER -Force |
272
+ Where-Object {
273
+ $_.Name -ne "node_modules" -and
274
+ $_.Name -ne "plain_modules" -and
275
+ $_.Name -ne "package-lock.json"
276
+ } | Remove-Item -Recurse -Force
277
+
278
+ if ($env:VERBOSE -eq "1") {
279
+ Write-Host "Cleanup completed, keeping 'node_modules' and 'package-lock.json'."
280
+ }
281
+ } else {
282
+ if ($env:VERBOSE -eq "1") {
283
+ Write-Host "Subfolder does not exist. Creating it..."
284
+ }
285
+
286
+ New-Item -ItemType Directory -Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER -Force | Out-Null
287
+ }
288
+
289
+ Copy-Item -Path "$ConformanceTestsFolder/*" -Destination $script:NODE_CONFORMANCE_TESTS_SUBFOLDER -Recurse -Force
290
+
291
+ # Move to the subfolder with Cypress tests
292
+ if (-not (Test-Path $script:NODE_CONFORMANCE_TESTS_SUBFOLDER)) {
293
+ Write-Host "Error: conformance tests Node folder '$script:NODE_CONFORMANCE_TESTS_SUBFOLDER' does not exist."
294
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
295
+ }
296
+
297
+ Push-Location $script:NODE_CONFORMANCE_TESTS_SUBFOLDER
298
+
299
+ # Temporarily allow stderr output without throwing (npm may write warnings to stderr)
300
+ # ForEach-Object converts ErrorRecord objects (from stderr) to plain strings to avoid verbose error formatting
301
+ $ErrorActionPreference = 'Continue'
302
+ $npmInstallOutput = npm install cypress --save-dev --prefer-offline --no-audit --no-fund --loglevel error 2>&1 | ForEach-Object { if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } } | Out-String
303
+ $ErrorActionPreference = 'Stop'
304
+ $npmInstallOutput -split "`n" | Where-Object { $_ -notmatch $NPM_INSTALL_OUTPUT_FILTER } | ForEach-Object {
305
+ if ($_.Trim()) { Write-Host $_ }
306
+ }
307
+
308
+ if ($env:VERBOSE -eq "1") {
309
+ Write-Host "Running Cypress conformance tests..."
310
+ }
311
+
312
+ $ErrorActionPreference = 'Continue'
313
+ $cypress_info_output = npx cypress info 2>&1 | ForEach-Object { if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } } | Out-String
314
+ $ErrorActionPreference = 'Stop'
315
+ $CYPRESS_BROWSER_FLAG = ""
316
+ if ($cypress_info_output -match "(?i)chrome") {
317
+ $CYPRESS_BROWSER_FLAG = "--browser=chrome"
318
+ }
319
+ Write-Host "CYPRESS_BROWSER_FLAG: $(if ($CYPRESS_BROWSER_FLAG) { $CYPRESS_BROWSER_FLAG } else { 'none' })"
320
+
321
+ $env:BROWSERSLIST_IGNORE_OLD_DATA = "1"
322
+ if ($CYPRESS_BROWSER_FLAG) {
323
+ npx cypress run $CYPRESS_BROWSER_FLAG --config video=false 2>$null
324
+ } else {
325
+ npx cypress run --config video=false 2>$null
326
+ }
327
+ $cypress_run_result = $LASTEXITCODE
328
+
329
+ if ($cypress_run_result -ne 0) {
330
+ if ($env:VERBOSE -eq "1") {
331
+ Write-Host "Error: Cypress conformance tests have failed."
332
+ }
333
+ exit 1
334
+ }
335
+ } finally {
336
+ Cleanup
337
+ }
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env pwsh
2
+
3
+ $ErrorActionPreference = 'Stop'
4
+
5
+ $UNRECOVERABLE_ERROR_EXIT_CODE = 69
6
+
7
+ # Check if build folder name is provided
8
+ if (-not $args[0]) {
9
+ Write-Host "Error: No build folder name provided."
10
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
11
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
12
+ }
13
+
14
+ # Check if conformance tests folder name is provided
15
+ if (-not $args[1]) {
16
+ Write-Host "Error: No conformance tests folder name provided."
17
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
18
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
19
+ }
20
+
21
+ $BuildFolder = $args[0]
22
+ $ConformanceTestsFolder = $args[1]
23
+
24
+ $current_dir = Get-Location
25
+
26
+ # Resolve conformance tests folder to an absolute path so it can be used
27
+ # from the build subfolder (where we'll Push-Location to next).
28
+ if (-not [System.IO.Path]::IsPathRooted($ConformanceTestsFolder)) {
29
+ $ConformanceTestsFolder = Join-Path $current_dir $ConformanceTestsFolder
30
+ }
31
+
32
+ # Working folder lives in the system temp directory. $BuildFolder may be an
33
+ # absolute path, so only its leaf name is used to build the working folder name.
34
+ $GO_BUILD_SUBFOLDER = Join-Path ([System.IO.Path]::GetTempPath()) "go_$(Split-Path $BuildFolder -Leaf)"
35
+
36
+ if ($env:VERBOSE -eq "1") {
37
+ Write-Host "Preparing Go build subfolder: $GO_BUILD_SUBFOLDER"
38
+ }
39
+
40
+ # Check if the go build subfolder exists
41
+ if (Test-Path $GO_BUILD_SUBFOLDER) {
42
+ # Delete all files and folders inside
43
+ Get-ChildItem -Path $GO_BUILD_SUBFOLDER -Force | Remove-Item -Recurse -Force
44
+
45
+ if ($env:VERBOSE -eq "1") {
46
+ Write-Host "Cleanup completed."
47
+ }
48
+ } else {
49
+ if ($env:VERBOSE -eq "1") {
50
+ Write-Host "Subfolder does not exist. Creating it..."
51
+ }
52
+
53
+ New-Item -ItemType Directory -Path $GO_BUILD_SUBFOLDER -Force | Out-Null
54
+ }
55
+
56
+ Copy-Item -Path "$BuildFolder/*" -Destination $GO_BUILD_SUBFOLDER -Recurse -Force
57
+
58
+ # Move to the subfolder
59
+ if (-not (Test-Path $GO_BUILD_SUBFOLDER)) {
60
+ Write-Host "Error: Go build folder '$GO_BUILD_SUBFOLDER' does not exist."
61
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
62
+ }
63
+
64
+ Push-Location $GO_BUILD_SUBFOLDER
65
+
66
+ try {
67
+ Write-Host "Runinng go get in the build folder..."
68
+ go get
69
+
70
+ # Move to conformance tests folder
71
+ Set-Location $ConformanceTestsFolder
72
+ if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) {
73
+ Write-Host "Error: Conformance tests folder '$ConformanceTestsFolder' does not exist."
74
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
75
+ }
76
+
77
+ Write-Host "Checking for go.mod in conformance test directory..."
78
+ if (Test-Path "go.mod") {
79
+ Write-Host "Running go get in conformance test directory..."
80
+ go get
81
+ } else {
82
+ Write-Host "No go.mod found in conformance test directory, skipping go get"
83
+ }
84
+
85
+ # Move back to build directory
86
+ Set-Location $GO_BUILD_SUBFOLDER
87
+
88
+ # Execute Go lang conformance tests
89
+ Write-Host "Running Golang conformance tests...`n"
90
+
91
+ # Temporarily allow stderr output without throwing (Go may write to stderr)
92
+ # ForEach-Object converts ErrorRecord objects (from stderr) to plain strings to avoid verbose error formatting
93
+ $ErrorActionPreference = 'Continue'
94
+ $output = go run (Join-Path $ConformanceTestsFolder "conformance_tests.go") 2>&1 | ForEach-Object { if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } } | Out-String
95
+ $exit_code = $LASTEXITCODE
96
+ $ErrorActionPreference = 'Stop'
97
+
98
+ # If there was an error, print the output and exit with the error code
99
+ if ($exit_code -ne 0) {
100
+ Write-Host $output
101
+ exit $exit_code
102
+ }
103
+
104
+ # Exit with the exit code of the test command
105
+ exit $exit_code
106
+ } finally {
107
+ Pop-Location
108
+ if (Test-Path $GO_BUILD_SUBFOLDER) {
109
+ Remove-Item -Path $GO_BUILD_SUBFOLDER -Recurse -Force -ErrorAction SilentlyContinue
110
+ }
111
+ }
@@ -0,0 +1,136 @@
1
+ #!/bin/bash
2
+ export JAVA_HOME=$(/usr/libexec/java_home -v 21)
3
+ java --version
4
+
5
+ # Check if build folder name is provided
6
+ if [ -z "$1" ]; then
7
+ printf "Error: No build folder name provided.\n"
8
+ printf "Usage: $0 <build_folder_name> <conformance_tests_folder>\n"
9
+ exit 1
10
+ fi
11
+
12
+ # Check if conformance tests folder name is provided
13
+ if [ -z "$2" ]; then
14
+ printf "Error: No conformance tests folder name provided.\n"
15
+ printf "Usage: $0 <build_folder_name> <conformance_tests_folder>\n"
16
+ exit 1
17
+ fi
18
+
19
+ current_dir=$(pwd)
20
+ printf "Current directory: $current_dir\n"
21
+
22
+ # Resolve the conformance tests folder to an absolute path so it can be used
23
+ # after changing into the working folder ($2 may be relative to the invocation
24
+ # directory on older renderers; newer renderers pass it as an absolute path).
25
+ case "$2" in
26
+ /*) CONFORMANCE_TESTS_SOURCE="$2" ;;
27
+ *) CONFORMANCE_TESTS_SOURCE="$current_dir/$2" ;;
28
+ esac
29
+
30
+ tree "$CONFORMANCE_TESTS_SOURCE"
31
+
32
+ # Working folders live in the system temp directory. $1 and $2 may be absolute
33
+ # paths, so only their basenames are used to build the working folder names.
34
+ JAVA_BUILD_SUBFOLDER="/tmp/java_$(basename "$1")"
35
+ CONFORMANCE_TESTS_FOLDER="/tmp/java_conformance_$(basename "$2")"
36
+
37
+ trap 'rm -rf "$JAVA_BUILD_SUBFOLDER" "$CONFORMANCE_TESTS_FOLDER"' EXIT
38
+
39
+ if [ "${VERBOSE:-}" -eq 1 ] 2>/dev/null; then
40
+ printf "Preparing Java build subfolder: $JAVA_BUILD_SUBFOLDER\n"
41
+ fi
42
+
43
+ rm -rf "$JAVA_BUILD_SUBFOLDER"
44
+ mkdir -p "$JAVA_BUILD_SUBFOLDER"
45
+
46
+ # Conformance tests live in the conformance tests folder and nowhere else. One in the
47
+ # build folder is in the wrong place: nothing would run it as part of the suite. Refuse.
48
+ MISPLACED=$( (grep -rlE --exclude=".turri*" --exclude-dir=target --exclude-dir=.m2 \
49
+ "conformance tests of (functionality [0-9]|the spec)|acceptance test [0-9]+ of functionality" "$1" 2>/dev/null; \
50
+ find "$1" -type f \( -ipath "*conformance*" -o -ipath "*acceptance*" \) -iname "*test*" \
51
+ -not -name ".turri*" -not -path "*/target/*" -not -path "*/.m2/*" 2>/dev/null) | sort -u)
52
+ if [ -n "$MISPLACED" ]; then
53
+ printf "Error: conformance tests found in the build folder %s - they belong in the conformance tests folder %s:\n%s\n" "$1" "$2" "$MISPLACED" >&2
54
+ exit 1
55
+ fi
56
+
57
+ cp -R "$1"/* "$JAVA_BUILD_SUBFOLDER"
58
+ printf "Copied from $1 to $JAVA_BUILD_SUBFOLDER...\n"
59
+
60
+ # Move to the subfolder
61
+ cd "$JAVA_BUILD_SUBFOLDER" 2>/dev/null
62
+ printf "Moved to $JAVA_BUILD_SUBFOLDER...\n"
63
+
64
+ if [ $? -ne 0 ]; then
65
+ printf "Error: Java build folder '$JAVA_BUILD_SUBFOLDER' does not exist.\n"
66
+ exit 2
67
+ fi
68
+
69
+ echo "Runinng maven install in $(pwd)..."
70
+ output=$(mvn clean install -DskipTests 2>&1)
71
+ exit_code=$?
72
+
73
+ # If there was an error, print the output and exit with the error code
74
+ if [ $exit_code -ne 0 ]; then
75
+ echo "Command failed: mvn clean install -DskipTests"
76
+ echo "Error: Running maven build failed with exit code $exit_code"
77
+ echo "Output: $output"
78
+ exit $exit_code
79
+ fi
80
+
81
+ cd "$current_dir" 2>/dev/null
82
+ printf "Moved to $current_dir...\n"
83
+ printf "Preparing Java conformance tests subfolder: $CONFORMANCE_TESTS_FOLDER\n"
84
+
85
+ rm -rf "$CONFORMANCE_TESTS_FOLDER"
86
+ mkdir -p "$CONFORMANCE_TESTS_FOLDER"
87
+
88
+ cp -R "$CONFORMANCE_TESTS_SOURCE"/* "$CONFORMANCE_TESTS_FOLDER"
89
+ printf "Copied from $CONFORMANCE_TESTS_SOURCE to $CONFORMANCE_TESTS_FOLDER...\n"
90
+
91
+ # Move to the subfolder
92
+ cd "$CONFORMANCE_TESTS_FOLDER" 2>/dev/null
93
+ printf "Moved to $CONFORMANCE_TESTS_FOLDER...\n"
94
+
95
+ if [ $? -ne 0 ]; then
96
+ printf "Error: Java conformance tests folder '$CONFORMANCE_TESTS_FOLDER' does not exist.\n"
97
+ exit 2
98
+ fi
99
+
100
+ echo "Runinng maven install in $(pwd)..."
101
+ output=$(mvn clean install -DskipTests 2>&1)
102
+ exit_code=$?
103
+
104
+ # If there was an error, print the output and exit with the error code
105
+ if [ $exit_code -ne 0 ]; then
106
+ echo "Command failed: mvn clean install -DskipTests"
107
+ echo "Error: Running maven build failed with exit code $exit_code"
108
+ echo "Output: $output"
109
+ exit $exit_code
110
+ fi
111
+
112
+ # Static checks of the conformance tests - their own Maven project, so only their findings: compiled with every javac
113
+ # lint warning an error, the flags pinned here rather than in the tests' pom. A formatter runs only when the test reqs
114
+ # name one.
115
+ STATIC_CHECKS_FAILED=80
116
+ echo "Static checks of the conformance tests in $(pwd)..."
117
+ echo "+ mvn -Dmaven.compiler.showWarnings=true -Dmaven.compiler.failOnWarning=true -Dmaven.compiler.compilerArgument=-Xlint:all test-compile"
118
+ mvn -Dmaven.compiler.showWarnings=true -Dmaven.compiler.failOnWarning=true -Dmaven.compiler.compilerArgument=-Xlint:all test-compile
119
+ CHECKS=$?
120
+ [ "$CHECKS" -eq 0 ] && echo "Static checks: passed" || echo "Static checks: FAILED - the findings are above"
121
+
122
+ # Execute all Java conformance tests in the subfolder - whatever the checks said, so one run reports both
123
+ echo "Running Java conformance tests in $(pwd)..."
124
+ output=$(mvn test 2>&1)
125
+ exit_code=$?
126
+
127
+ # The suite's own exit code when it failed; 80 when only the static checks of the tests did; 0 when both pass
128
+ if [ $exit_code -ne 0 ]; then
129
+ echo "$output"
130
+ exit $exit_code
131
+ fi
132
+ if [ "$CHECKS" -ne 0 ]; then
133
+ echo "The conformance tests pass, and their static checks do not."
134
+ exit $STATIC_CHECKS_FAILED
135
+ fi
136
+ exit 0
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env pwsh
2
+
3
+ $ErrorActionPreference = 'Stop'
4
+
5
+ $UNRECOVERABLE_ERROR_EXIT_CODE = 69
6
+
7
+ # Check if build folder name is provided
8
+ if (-not $args[0]) {
9
+ Write-Host "Error: No build folder name provided."
10
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
11
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
12
+ }
13
+
14
+ # Check if conformance tests folder name is provided
15
+ if (-not $args[1]) {
16
+ Write-Host "Error: No conformance tests folder name provided."
17
+ Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
18
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
19
+ }
20
+
21
+ $BuildFolder = $args[0]
22
+ $ConformanceTestsFolder = $args[1]
23
+
24
+ # Try to find Python interpreter (python3 first, then python)
25
+ if (Get-Command python3 -ErrorAction SilentlyContinue) {
26
+ $PYTHON_CMD = "python3"
27
+ } elseif (Get-Command python -ErrorAction SilentlyContinue) {
28
+ $PYTHON_CMD = "python"
29
+ } else {
30
+ Write-Host "Error: Python interpreter not found. Please install Python."
31
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
32
+ }
33
+
34
+ $current_dir = Get-Location
35
+
36
+ # Resolve conformance tests folder to an absolute path so it can be used
37
+ # from the build subfolder (where we'll Push-Location to next).
38
+ if (-not [System.IO.Path]::IsPathRooted($ConformanceTestsFolder)) {
39
+ $ConformanceTestsFolder = Join-Path $current_dir $ConformanceTestsFolder
40
+ }
41
+
42
+ # Working folder lives in the system temp directory. $BuildFolder may be an
43
+ # absolute path, so only its leaf name is used to build the working folder name.
44
+ $PYTHON_BUILD_SUBFOLDER = Join-Path ([System.IO.Path]::GetTempPath()) "python_$(Split-Path $BuildFolder -Leaf)"
45
+
46
+ if ($env:VERBOSE -eq "1") {
47
+ Write-Host "Preparing Python build subfolder: $PYTHON_BUILD_SUBFOLDER"
48
+ }
49
+
50
+ # Check if the Python build subfolder exists
51
+ if (Test-Path $PYTHON_BUILD_SUBFOLDER) {
52
+ # Delete all files and folders inside
53
+ Get-ChildItem -Path $PYTHON_BUILD_SUBFOLDER -Force | Remove-Item -Recurse -Force
54
+
55
+ if ($env:VERBOSE -eq "1") {
56
+ Write-Host "Cleanup completed."
57
+ }
58
+ } else {
59
+ if ($env:VERBOSE -eq "1") {
60
+ Write-Host "Subfolder does not exist. Creating it..."
61
+ }
62
+
63
+ New-Item -ItemType Directory -Path $PYTHON_BUILD_SUBFOLDER -Force | Out-Null
64
+ }
65
+
66
+ Copy-Item -Path "$BuildFolder/*" -Destination $PYTHON_BUILD_SUBFOLDER -Recurse -Force
67
+
68
+ # Move to the subfolder
69
+ if (-not (Test-Path $PYTHON_BUILD_SUBFOLDER)) {
70
+ Write-Host "Error: Python build folder '$PYTHON_BUILD_SUBFOLDER' does not exist."
71
+ exit $UNRECOVERABLE_ERROR_EXIT_CODE
72
+ }
73
+
74
+ Push-Location $PYTHON_BUILD_SUBFOLDER
75
+
76
+ try {
77
+ # Execute all Python conformance tests in the build folder
78
+ Write-Host "Running Python conformance tests...`n"
79
+
80
+ # Temporarily allow stderr output without throwing (Python unittest writes progress to stderr)
81
+ # ForEach-Object converts ErrorRecord objects (from stderr) to plain strings to avoid verbose error formatting
82
+ $ErrorActionPreference = 'Continue'
83
+ $output = & $PYTHON_CMD -m unittest discover -b -s $ConformanceTestsFolder 2>&1 | ForEach-Object { if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } } | Out-String
84
+ $exit_code = $LASTEXITCODE
85
+ $ErrorActionPreference = 'Stop'
86
+
87
+ # Echo the original output
88
+ Write-Host $output
89
+
90
+ # Check if no tests were discovered
91
+ if ($output -match "Ran 0 tests in") {
92
+ Write-Host "`nError: No unittests discovered."
93
+ exit 1
94
+ }
95
+
96
+ # Exit with the exit code of the unittest command
97
+ exit $exit_code
98
+ } finally {
99
+ Pop-Location
100
+ if (Test-Path $PYTHON_BUILD_SUBFOLDER) {
101
+ Remove-Item -Path $PYTHON_BUILD_SUBFOLDER -Recurse -Force -ErrorAction SilentlyContinue
102
+ }
103
+ }