mxrb 0.1.0

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 (237) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.de-DE.md +108 -0
  4. data/README.md +172 -0
  5. data/README.pt-BR.md +109 -0
  6. data/bin/mxrb +1613 -0
  7. data/docs/README.md +10 -0
  8. data/docs/de-DE/README.md +24 -0
  9. data/docs/de-DE/architectural-patterns.md +26 -0
  10. data/docs/de-DE/architectural-standard.md +48 -0
  11. data/docs/de-DE/architecture.md +76 -0
  12. data/docs/de-DE/compiler.md +162 -0
  13. data/docs/de-DE/conventions.md +19 -0
  14. data/docs/de-DE/design-system.md +52 -0
  15. data/docs/de-DE/entity-dsl.md +53 -0
  16. data/docs/de-DE/native-runtime-quality-report.md +74 -0
  17. data/docs/de-DE/oql-sql.md +211 -0
  18. data/docs/de-DE/platform-api-integration.md +36 -0
  19. data/docs/de-DE/platform-operations.md +243 -0
  20. data/docs/de-DE/project-structure.md +32 -0
  21. data/docs/de-DE/ruby-first-roadmap.md +116 -0
  22. data/docs/de-DE/scaffolds.md +59 -0
  23. data/docs/de-DE/semantic-refactoring.md +56 -0
  24. data/docs/de-DE/team-server.md +33 -0
  25. data/docs/de-DE/validation-matrix.md +64 -0
  26. data/docs/de-DE/vetclinic-acceptance.md +24 -0
  27. data/docs/de-DE/writing.md +138 -0
  28. data/docs/en-US/README.md +24 -0
  29. data/docs/en-US/architectural-patterns.md +151 -0
  30. data/docs/en-US/architectural-standard.md +89 -0
  31. data/docs/en-US/architecture.md +170 -0
  32. data/docs/en-US/compiler.md +157 -0
  33. data/docs/en-US/conventions.md +82 -0
  34. data/docs/en-US/design-system.md +163 -0
  35. data/docs/en-US/entity-dsl.md +53 -0
  36. data/docs/en-US/native-runtime-quality-report.md +73 -0
  37. data/docs/en-US/oql-sql.md +201 -0
  38. data/docs/en-US/platform-api-integration.md +36 -0
  39. data/docs/en-US/platform-operations.md +244 -0
  40. data/docs/en-US/project-structure.md +49 -0
  41. data/docs/en-US/ruby-first-roadmap.md +186 -0
  42. data/docs/en-US/scaffolds.md +57 -0
  43. data/docs/en-US/semantic-refactoring.md +198 -0
  44. data/docs/en-US/team-server.md +32 -0
  45. data/docs/en-US/validation-matrix.md +257 -0
  46. data/docs/en-US/vetclinic-acceptance.md +23 -0
  47. data/docs/en-US/writing.md +655 -0
  48. data/docs/pt-BR/README.md +24 -0
  49. data/docs/pt-BR/architectural-patterns.md +25 -0
  50. data/docs/pt-BR/architectural-standard.md +533 -0
  51. data/docs/pt-BR/architecture.md +300 -0
  52. data/docs/pt-BR/compiler.md +162 -0
  53. data/docs/pt-BR/conventions.md +19 -0
  54. data/docs/pt-BR/design-system.md +65 -0
  55. data/docs/pt-BR/entity-dsl.md +116 -0
  56. data/docs/pt-BR/native-runtime-quality-report.md +73 -0
  57. data/docs/pt-BR/oql-sql.md +208 -0
  58. data/docs/pt-BR/platform-api-integration.md +36 -0
  59. data/docs/pt-BR/platform-operations.md +260 -0
  60. data/docs/pt-BR/project-structure.md +32 -0
  61. data/docs/pt-BR/ruby-first-roadmap.md +239 -0
  62. data/docs/pt-BR/scaffolds.md +104 -0
  63. data/docs/pt-BR/semantic-refactoring.md +55 -0
  64. data/docs/pt-BR/team-server.md +59 -0
  65. data/docs/pt-BR/validation-matrix.md +86 -0
  66. data/docs/pt-BR/vetclinic-acceptance.md +50 -0
  67. data/docs/pt-BR/writing.md +177 -0
  68. data/examples/sudoku_evaluation.rb +14 -0
  69. data/examples/sudoku_functional_test.rb +28 -0
  70. data/lib/mxrb/architecture/graph.rb +124 -0
  71. data/lib/mxrb/architecture/validator.rb +98 -0
  72. data/lib/mxrb/benchmark.rb +33 -0
  73. data/lib/mxrb/compare.rb +390 -0
  74. data/lib/mxrb/compiler/adapter.rb +96 -0
  75. data/lib/mxrb/compiler/artifact_document_compiler.rb +102 -0
  76. data/lib/mxrb/compiler/artifact_materializer.rb +53 -0
  77. data/lib/mxrb/compiler/client_model_materializer.rb +42 -0
  78. data/lib/mxrb/compiler/code_action_document_compiler.rb +64 -0
  79. data/lib/mxrb/compiler/code_action_materializer.rb +35 -0
  80. data/lib/mxrb/compiler/code_action_type_compiler.rb +32 -0
  81. data/lib/mxrb/compiler/combo_box_bundle_compiler.rb +314 -0
  82. data/lib/mxrb/compiler/compatibility_analyzer.rb +169 -0
  83. data/lib/mxrb/compiler/constants_materializer.rb +111 -0
  84. data/lib/mxrb/compiler/data_grid_bundle_compiler.rb +290 -0
  85. data/lib/mxrb/compiler/database_connector_action_compiler.rb +280 -0
  86. data/lib/mxrb/compiler/deployment_asset_copier.rb +60 -0
  87. data/lib/mxrb/compiler/deployment_bootstrapper.rb +208 -0
  88. data/lib/mxrb/compiler/deployment_materializer.rb +43 -0
  89. data/lib/mxrb/compiler/deployment_metadata.rb +64 -0
  90. data/lib/mxrb/compiler/domain_document_compiler.rb +153 -0
  91. data/lib/mxrb/compiler/domain_model_materializer.rb +35 -0
  92. data/lib/mxrb/compiler/domain_security_compiler.rb +82 -0
  93. data/lib/mxrb/compiler/gallery_bundle_compiler.rb +190 -0
  94. data/lib/mxrb/compiler/generic_widget_bundle_compiler.rb +281 -0
  95. data/lib/mxrb/compiler/image_bundle_compiler.rb +216 -0
  96. data/lib/mxrb/compiler/java_proxy_generator.rb +509 -0
  97. data/lib/mxrb/compiler/legacy_data_grid_compiler.rb +267 -0
  98. data/lib/mxrb/compiler/legacy_page_builder.rb +287 -0
  99. data/lib/mxrb/compiler/mda.rb +99 -0
  100. data/lib/mxrb/compiler/microflow_document_compiler.rb +85 -0
  101. data/lib/mxrb/compiler/microflow_materializer.rb +48 -0
  102. data/lib/mxrb/compiler/microflow_node_compiler.rb +250 -0
  103. data/lib/mxrb/compiler/model_package.rb +116 -0
  104. data/lib/mxrb/compiler/model_values.rb +67 -0
  105. data/lib/mxrb/compiler/nanoflow_program_compiler.rb +483 -0
  106. data/lib/mxrb/compiler/navigation_document_compiler.rb +93 -0
  107. data/lib/mxrb/compiler/packager.rb +100 -0
  108. data/lib/mxrb/compiler/page_bundle_builder.rb +56 -0
  109. data/lib/mxrb/compiler/page_bundle_compiler.rb +2004 -0
  110. data/lib/mxrb/compiler/page_document_compiler.rb +77 -0
  111. data/lib/mxrb/compiler/portable_packager.rb +356 -0
  112. data/lib/mxrb/compiler/project_jar_archive.rb +84 -0
  113. data/lib/mxrb/compiler/project_jar_builder.rb +121 -0
  114. data/lib/mxrb/compiler/project_materializer.rb +139 -0
  115. data/lib/mxrb/compiler/project_model_orderer.rb +52 -0
  116. data/lib/mxrb/compiler/runtime_data_types.rb +31 -0
  117. data/lib/mxrb/compiler/runtime_model_schema.rb +90 -0
  118. data/lib/mxrb/compiler/schemas/runtime-10.24.0.73019.json +1052 -0
  119. data/lib/mxrb/compiler/schemas/runtime-11.json +1215 -0
  120. data/lib/mxrb/compiler/schemas/runtime-6.10.8.json +1148 -0
  121. data/lib/mxrb/compiler/schemas/runtime-7.17.0.json +1144 -0
  122. data/lib/mxrb/compiler/schemas/runtime-7.5.0.json +1215 -0
  123. data/lib/mxrb/compiler/schemas/runtime-9.6.1.29396.json +868 -0
  124. data/lib/mxrb/compiler/schemas/system-model-10.24.0.73019.b64 +1135 -0
  125. data/lib/mxrb/compiler/schemas/system-model-11.12.1.b64 +815 -0
  126. data/lib/mxrb/compiler/schemas/system-model-6.10.8.b64 +497 -0
  127. data/lib/mxrb/compiler/schemas/system-model-7.17.0.b64 +519 -0
  128. data/lib/mxrb/compiler/schemas/system-model-7.5.0.b64 +504 -0
  129. data/lib/mxrb/compiler/schemas/system-model-9.6.1.29396.b64 +816 -0
  130. data/lib/mxrb/compiler/security_materializer.rb +104 -0
  131. data/lib/mxrb/compiler/settings_document_compiler.rb +45 -0
  132. data/lib/mxrb/compiler/settings_materializer.rb +25 -0
  133. data/lib/mxrb/compiler/source_model.rb +128 -0
  134. data/lib/mxrb/compiler/system_model_seed.rb +88 -0
  135. data/lib/mxrb/compiler/system_queue_materializer.rb +54 -0
  136. data/lib/mxrb/compiler/system_text_materializer.rb +49 -0
  137. data/lib/mxrb/compiler/translation_materializer.rb +95 -0
  138. data/lib/mxrb/compiler/web_bundle_builder.rb +155 -0
  139. data/lib/mxrb/compiler/web_list_data_source.rb +139 -0
  140. data/lib/mxrb/compiler/web_operation_compiler.rb +614 -0
  141. data/lib/mxrb/compiler/web_shell_materializer.rb +194 -0
  142. data/lib/mxrb/compiler/widget_package_extractor.rb +63 -0
  143. data/lib/mxrb/doctor.rb +116 -0
  144. data/lib/mxrb/dsl/builder.rb +1636 -0
  145. data/lib/mxrb/errors.rb +18 -0
  146. data/lib/mxrb/evaluation.rb +131 -0
  147. data/lib/mxrb/exporter.rb +1716 -0
  148. data/lib/mxrb/frontend/migrator.rb +775 -0
  149. data/lib/mxrb/functional.rb +307 -0
  150. data/lib/mxrb/github/annotator.rb +161 -0
  151. data/lib/mxrb/initializer.rb +257 -0
  152. data/lib/mxrb/integrity/validator.rb +136 -0
  153. data/lib/mxrb/io/bson_codec.rb +145 -0
  154. data/lib/mxrb/io/mpr_file.rb +558 -0
  155. data/lib/mxrb/io/mxunit_codec.rb +42 -0
  156. data/lib/mxrb/marketplace.rb +380 -0
  157. data/lib/mxrb/model/association.rb +98 -0
  158. data/lib/mxrb/model/attribute.rb +100 -0
  159. data/lib/mxrb/model/connector.rb +17 -0
  160. data/lib/mxrb/model/design_materializer.rb +133 -0
  161. data/lib/mxrb/model/design_migration.rb +126 -0
  162. data/lib/mxrb/model/design_system.rb +111 -0
  163. data/lib/mxrb/model/domain_model.rb +51 -0
  164. data/lib/mxrb/model/entity.rb +180 -0
  165. data/lib/mxrb/model/menu.rb +38 -0
  166. data/lib/mxrb/model/microflow.rb +100 -0
  167. data/lib/mxrb/model/module.rb +142 -0
  168. data/lib/mxrb/model/navigation.rb +127 -0
  169. data/lib/mxrb/model/page.rb +410 -0
  170. data/lib/mxrb/model/project.rb +187 -0
  171. data/lib/mxrb/model/unit.rb +48 -0
  172. data/lib/mxrb/module_initializer.rb +75 -0
  173. data/lib/mxrb/official_marketplace/content_api.rb +292 -0
  174. data/lib/mxrb/official_marketplace/dependency_resolver.rb +329 -0
  175. data/lib/mxrb/official_marketplace/lifecycle.rb +367 -0
  176. data/lib/mxrb/official_marketplace/module_package_importer.rb +318 -0
  177. data/lib/mxrb/official_marketplace/widget_package_installer.rb +414 -0
  178. data/lib/mxrb/official_marketplace.rb +720 -0
  179. data/lib/mxrb/oql/analyzer.rb +155 -0
  180. data/lib/mxrb/oql/index_advisor.rb +85 -0
  181. data/lib/mxrb/oql/plan_analyzer.rb +185 -0
  182. data/lib/mxrb/oql/server.rb +132 -0
  183. data/lib/mxrb/oql/sql_server_plan_analyzer.rb +190 -0
  184. data/lib/mxrb/oql/sql_server_workload_analyzer.rb +80 -0
  185. data/lib/mxrb/oql/workload_analyzer.rb +175 -0
  186. data/lib/mxrb/oql/workload_baseline.rb +60 -0
  187. data/lib/mxrb/oql.rb +424 -0
  188. data/lib/mxrb/project_lifecycle.rb +76 -0
  189. data/lib/mxrb/protocols/plan.rb +86 -0
  190. data/lib/mxrb/protocols.rb +123 -0
  191. data/lib/mxrb/runtime/database_workspace.rb +677 -0
  192. data/lib/mxrb/runtime/docker_executor.rb +41 -0
  193. data/lib/mxrb/runtime/docker_workspace.rb +29 -0
  194. data/lib/mxrb/runtime/executor.rb +169 -0
  195. data/lib/mxrb/runtime/java_locator.rb +26 -0
  196. data/lib/mxrb/runtime/native.rb +474 -0
  197. data/lib/mxrb/runtime/sql_server_database.rb +146 -0
  198. data/lib/mxrb/runtime/toolchain.rb +82 -0
  199. data/lib/mxrb/scaffold/cli.rb +113 -0
  200. data/lib/mxrb/scaffold/generator.rb +246 -0
  201. data/lib/mxrb/scaffold/help.rb +80 -0
  202. data/lib/mxrb/scaffold/page_templates.rb +54 -0
  203. data/lib/mxrb/scaffold/recipes.rb +198 -0
  204. data/lib/mxrb/scaffold/registry.rb +82 -0
  205. data/lib/mxrb/scaffold/templates.rb +723 -0
  206. data/lib/mxrb/scaffold/transaction.rb +84 -0
  207. data/lib/mxrb/schema/tables.rb +55 -0
  208. data/lib/mxrb/semantic/analyzer.rb +473 -0
  209. data/lib/mxrb/semantic/batch_plan.rb +68 -0
  210. data/lib/mxrb/semantic/domain_mutator.rb +419 -0
  211. data/lib/mxrb/semantic/embedder.rb +51 -0
  212. data/lib/mxrb/semantic/extractor.rb +290 -0
  213. data/lib/mxrb/semantic/index.rb +623 -0
  214. data/lib/mxrb/semantic/inliner.rb +216 -0
  215. data/lib/mxrb/semantic/mover.rb +153 -0
  216. data/lib/mxrb/semantic/onnx_embedder.rb +34 -0
  217. data/lib/mxrb/semantic/remover.rb +70 -0
  218. data/lib/mxrb/semantic/renamer.rb +211 -0
  219. data/lib/mxrb/semantic/tfidf_embedder.rb +46 -0
  220. data/lib/mxrb/semantic/vec_store.rb +75 -0
  221. data/lib/mxrb/team_server.rb +390 -0
  222. data/lib/mxrb/templates/project/10.24.0.73019.json +32 -0
  223. data/lib/mxrb/templates/project/11.12.1.json +32 -0
  224. data/lib/mxrb/templates/project/6.10.8.json +50 -0
  225. data/lib/mxrb/templates/project/7.17.0.json +50 -0
  226. data/lib/mxrb/templates/project/7.5.0.json +50 -0
  227. data/lib/mxrb/templates/project/9.6.1.29396.json +50 -0
  228. data/lib/mxrb/version.rb +5 -0
  229. data/lib/mxrb/widget_package.rb +338 -0
  230. data/lib/mxrb/widget_synchronizer.rb +31 -0
  231. data/lib/mxrb/writer.rb +3775 -0
  232. data/lib/mxrb.rb +188 -0
  233. data/marketplace/catalog.json +10 -0
  234. data/marketplace/modules/shared-kernel/domain/README.md +4 -0
  235. data/marketplace/modules/shared-kernel/module.rb +5 -0
  236. data/marketplace/modules/shared-kernel/mxrb-module.json +9 -0
  237. metadata +447 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mxrb
4
+ module Runtime
5
+ # Executes natively compiled portable applications in a Runtime container.
6
+ class DockerExecutor < Executor
7
+ private
8
+
9
+ def validate_environment!
10
+ raise ToolchainError, "Mendix Runtime #{@plan.runtime_path} is unavailable" unless @plan.available?
11
+ _, status = capture("docker", "version", "--format", "{{.Server.Version}}")
12
+ raise ToolchainError, "Docker daemon is unavailable" unless status.success?
13
+ end
14
+
15
+ def start_runtime(package, root)
16
+ runtime = File.join(root, "runtime")
17
+ FileUtils.mkdir_p(runtime)
18
+ output, status = capture("unzip", "-q", package, "-d", runtime)
19
+ raise FunctionalTestError, "could not unpack runtime:\n#{output}" unless status.success?
20
+
21
+ command = [
22
+ "docker", "run", "--rm", "--stop-timeout", "10",
23
+ "--user", "#{Process.uid}:#{Process.gid}",
24
+ "--mount", bind_mount(runtime, "/mendix", readonly: false),
25
+ "-e", "M2EE_ADMIN_PASS=mxrb-functional-test",
26
+ "-e", "HOME=/tmp",
27
+ "-w", "/mendix",
28
+ @plan.runtime_image,
29
+ "./bin/start", "etc/Default"
30
+ ]
31
+ collect_runtime({}, command, root)
32
+ end
33
+
34
+ def bind_mount(source, target, readonly:)
35
+ values = ["type=bind", "source=#{source}", "target=#{target}"]
36
+ values << "readonly" if readonly
37
+ values.join(",")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mxrb
4
+ module Runtime
5
+ # Produces the argv-safe command for a natively compiled Runtime package.
6
+ class DockerWorkspace
7
+ attr_reader :project_path, :plan
8
+
9
+ def initialize(project_path, plan, workspace_size: "8g")
10
+ @project_path = File.expand_path(project_path)
11
+ @plan = plan
12
+ @workspace_size = workspace_size.to_s
13
+ end
14
+
15
+ def runtime_command(package_volume:, http_port: 8080, admin_port: 8090)
16
+ [
17
+ "docker", "run", "--rm",
18
+ "--mount", "type=volume,source=#{package_volume},target=/mendix",
19
+ "--tmpfs", "/mendix/data:exec,size=2g",
20
+ "-p", "#{Integer(http_port)}:8080",
21
+ "-p", "#{Integer(admin_port)}:8090",
22
+ "-e", "M2EE_ADMIN_PASS=mxrb-functional-test",
23
+ @plan.runtime_image,
24
+ "./bin/start", "etc/Default"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "open3"
5
+ require "tmpdir"
6
+
7
+ module Mxrb
8
+ module Runtime
9
+ Execution = Data.define(
10
+ :result, :check_output, :build_output, :runtime_output, :elapsed
11
+ ) do
12
+ def passed? = result.passed?
13
+ end
14
+
15
+ # Builds a disposable project natively and converts the Runtime protocol
16
+ # back into Ruby result objects.
17
+ class Executor
18
+ STARTUP_ALLOWANCE = 120
19
+
20
+ def initialize(project_path, definition, plan: nil, java_home: ENV["JAVA_HOME"],
21
+ output: nil, clock: Process.method(:clock_gettime))
22
+ @project_path = File.expand_path(project_path)
23
+ @definition = definition
24
+ @plan = plan || Toolchain.new(@project_path).plan
25
+ @java_home = java_home && File.expand_path(java_home)
26
+ @output = output
27
+ @clock = clock
28
+ end
29
+
30
+ def run
31
+ validate_environment!
32
+ started = monotonic_time
33
+ Dir.mktmpdir("mxrb-functional-") do |root|
34
+ project = copy_project(root)
35
+ Functional::Instrumenter.new(project, @definition).instrument!
36
+ check_output = check(project, root)
37
+ package = build(project, root)
38
+ runtime_output = start_runtime(package, root)
39
+ result = Functional::LogParser.new.parse(runtime_output)
40
+ raise FunctionalTestError, "runtime stopped before the test suite completed" unless result.finished?
41
+
42
+ Execution.new(
43
+ result, check_output, build_output(package), runtime_output,
44
+ monotonic_time - started
45
+ )
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def validate_environment!
52
+ raise ToolchainError, "Mendix Runtime #{@plan.runtime_path} is unavailable" unless @plan.available?
53
+ unless @java_home && File.executable?(File.join(@java_home, "bin", "java"))
54
+ raise ToolchainError, "JAVA_HOME must point to a Java #{@plan.java_version} installation"
55
+ end
56
+ end
57
+
58
+ def copy_project(root)
59
+ source_dir = File.dirname(@project_path)
60
+ destination = File.join(root, "project")
61
+ FileUtils.mkdir_p(destination)
62
+ FileUtils.cp_r(
63
+ Dir.glob(File.join(source_dir, "*"), File::FNM_DOTMATCH)
64
+ .reject { [".", ".."].include?(File.basename(_1)) },
65
+ destination
66
+ )
67
+ File.join(destination, File.basename(@project_path))
68
+ end
69
+
70
+ def check(project, _root)
71
+ result = Mxrb.validate(project)
72
+ unless result.valid?
73
+ raise FunctionalTestError,
74
+ "MXRB validation found #{result.errors.size} error(s): #{result.errors.first}"
75
+ end
76
+
77
+ (["MXRB native validation passed"] + result.warnings.map { "warning: #{_1}" }).join("\n")
78
+ end
79
+
80
+ def build(project, root)
81
+ package = File.join(root, "runtime.zip")
82
+ deployment = File.join(File.dirname(project), 'deployment')
83
+ materialized = Compiler::DeploymentMaterializer.new(
84
+ project, deployment:, mendix_home: @plan.toolchain_path
85
+ ).materialize
86
+ jar = Compiler::ProjectJarBuilder.new(
87
+ project, deployment:, mendix_home: @plan.toolchain_path, java_home: @java_home
88
+ ).build
89
+ web = Compiler::WebBundleBuilder.new(
90
+ project, deployment:, mendix_home: @plan.toolchain_path
91
+ ).build
92
+ result = Compiler::PortablePackager.new(
93
+ project, deployment:, mendix_home: @plan.toolchain_path
94
+ ).pack(output: package, force: true)
95
+ @last_build_output = format(
96
+ 'MXRB native build: Mendix %s, %d stages, %d Java sources, %d classes, ' \
97
+ '%d web files, %d packaged files, sha256 %s',
98
+ materialized.mendix_version, materialized.stages.length, jar.sources, jar.classes,
99
+ web.files, result.files, result.sha256
100
+ )
101
+ package
102
+ rescue CompilationError => e
103
+ raise FunctionalTestError, "MXRB native build failed: #{e.message}"
104
+ end
105
+
106
+ def build_output(_package) = @last_build_output
107
+
108
+ def start_runtime(package, root)
109
+ runtime = File.join(root, "runtime")
110
+ FileUtils.mkdir_p(runtime)
111
+ output, status = capture("unzip", "-q", package, "-d", runtime)
112
+ raise FunctionalTestError, "could not unpack runtime:\n#{output}" unless status.success?
113
+
114
+ command = [File.join(runtime, "bin", "start"), "etc/Default"]
115
+ environment = {
116
+ "JAVA_HOME" => @java_home,
117
+ "M2EE_ADMIN_PASS" => "mxrb-functional-test"
118
+ }
119
+ collect_runtime(environment, command, runtime)
120
+ end
121
+
122
+ def collect_runtime(environment, command, directory)
123
+ transcript = +""
124
+ deadline = monotonic_time + STARTUP_ALLOWANCE + @definition.tests.sum(&:timeout)
125
+ Open3.popen2e(environment, *command, chdir: directory) do |stdin, stream, thread|
126
+ stdin.close
127
+ until transcript.include?("[MXRB_TEST] DONE")
128
+ remaining = deadline - monotonic_time
129
+ raise FunctionalTestError, "functional test runtime timed out" unless remaining.positive?
130
+
131
+ ready = ::IO.select([stream], nil, nil, remaining)
132
+ raise FunctionalTestError, "functional test runtime timed out" unless ready
133
+
134
+ line = stream.gets
135
+ break unless line
136
+
137
+ transcript << line
138
+ @output&.write(line)
139
+ end
140
+ ensure
141
+ terminate(thread)
142
+ end
143
+ transcript
144
+ end
145
+
146
+ def terminate(thread)
147
+ return unless thread&.alive?
148
+
149
+ Process.kill("TERM", thread.pid)
150
+ thread.join(10)
151
+ Process.kill("KILL", thread.pid) if thread.alive?
152
+ rescue Errno::ESRCH
153
+ nil
154
+ ensure
155
+ thread&.join
156
+ end
157
+
158
+ def capture(*command)
159
+ Open3.capture2e(*command)
160
+ end
161
+
162
+ def monotonic_time
163
+ @clock.call(Process::CLOCK_MONOTONIC)
164
+ rescue ArgumentError
165
+ @clock.call
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mxrb
4
+ module Runtime
5
+ # Resolves a version-compatible local JDK without invoking a version manager shim.
6
+ module JavaLocator
7
+ module_function
8
+
9
+ def resolve(major, configured: nil)
10
+ candidates = [configured, ENV['MXRB_JAVA_HOME'], ENV['JAVA_HOME']]
11
+ .compact.reject { _1.to_s.empty? }
12
+ candidates.concat(installed(major))
13
+ candidates.map { File.expand_path(_1) }
14
+ .find { File.executable?(File.join(_1, 'bin', 'java')) }
15
+ end
16
+
17
+ def installed(major)
18
+ %w[.asdf/installs/java .local/share/mise/installs/java].flat_map do |root|
19
+ Dir.glob(File.join(Dir.home, root, '*')).select do |path|
20
+ File.basename(path).match?(/(?:\A|[-_])#{Regexp.escape(major.to_s)}(?:[._-]|\z)/)
21
+ end
22
+ end.sort.reverse
23
+ end
24
+ end
25
+ end
26
+ end