tetra 2.0.7 → 2.0.8

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 (222) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -3
  3. data/README.md +5 -4
  4. data/bin/tetra +6 -4
  5. data/lib/template/bashrc +19 -14
  6. data/lib/template/bundled/apache-maven-3.9.12/LICENSE +616 -0
  7. data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/NOTICE +0 -6
  8. data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/mvn +9 -0
  9. data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/mvn.cmd +14 -0
  10. data/lib/template/bundled/{apache-maven-3.9.9/boot/plexus-classworlds-2.8.0.jar → apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar} +0 -0
  11. data/lib/template/bundled/apache-maven-3.9.12/lib/asm-9.9.jar +0 -0
  12. data/lib/template/bundled/apache-maven-3.9.12/lib/asm.license +29 -0
  13. data/lib/template/bundled/apache-maven-3.9.12/lib/commons-cli-1.11.0.jar +0 -0
  14. data/lib/template/bundled/apache-maven-3.9.12/lib/commons-codec-1.20.0.jar +0 -0
  15. data/lib/template/bundled/apache-maven-3.9.12/lib/error_prone_annotations-2.41.0.jar +0 -0
  16. data/lib/template/bundled/apache-maven-3.9.12/lib/failureaccess-1.0.3.jar +0 -0
  17. data/lib/template/bundled/apache-maven-3.9.12/lib/gson-2.13.2.jar +0 -0
  18. data/lib/template/bundled/apache-maven-3.9.12/lib/guava-33.5.0-jre.jar +0 -0
  19. data/lib/template/bundled/apache-maven-3.9.12/lib/guice-5.1.0-classes.jar +0 -0
  20. data/lib/template/bundled/{apache-maven-3.9.9/lib/jansi-2.4.1.jar → apache-maven-3.9.12/lib/jansi-2.4.2.jar} +0 -0
  21. data/lib/template/bundled/{apache-maven-3.9.9/lib/jansi-native/Windows/arm64/libjansi.so → apache-maven-3.9.12/lib/jansi-native/Windows/arm64/jansi.dll} +0 -0
  22. data/lib/template/bundled/apache-maven-3.9.12/lib/jspecify-1.0.0.jar +0 -0
  23. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-artifact-3.9.9.jar → apache-maven-3.9.12/lib/maven-artifact-3.9.12.jar} +0 -0
  24. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-builder-support-3.9.9.jar → apache-maven-3.9.12/lib/maven-builder-support-3.9.12.jar} +0 -0
  25. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-compat-3.9.9.jar → apache-maven-3.9.12/lib/maven-compat-3.9.12.jar} +0 -0
  26. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-core-3.9.9.jar → apache-maven-3.9.12/lib/maven-core-3.9.12.jar} +0 -0
  27. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-embedder-3.9.12.jar +0 -0
  28. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-model-3.9.12.jar +0 -0
  29. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-model-builder-3.9.9.jar → apache-maven-3.9.12/lib/maven-model-builder-3.9.12.jar} +0 -0
  30. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-plugin-api-3.9.12.jar +0 -0
  31. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-repository-metadata-3.9.12.jar +0 -0
  32. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-api-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-api-1.9.25.jar} +0 -0
  33. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-resolver-connector-basic-1.9.25.jar +0 -0
  34. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-impl-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-impl-1.9.25.jar} +0 -0
  35. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-named-locks-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-named-locks-1.9.25.jar} +0 -0
  36. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-provider-3.9.9.jar → apache-maven-3.9.12/lib/maven-resolver-provider-3.9.12.jar} +0 -0
  37. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-spi-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-spi-1.9.25.jar} +0 -0
  38. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-resolver-transport-file-1.9.25.jar +0 -0
  39. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-resolver-transport-http-1.9.25.jar +0 -0
  40. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-transport-wagon-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-transport-wagon-1.9.25.jar} +0 -0
  41. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-resolver-util-1.9.22.jar → apache-maven-3.9.12/lib/maven-resolver-util-1.9.25.jar} +0 -0
  42. data/lib/template/bundled/apache-maven-3.9.12/lib/maven-settings-3.9.12.jar +0 -0
  43. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-settings-builder-3.9.9.jar → apache-maven-3.9.12/lib/maven-settings-builder-3.9.12.jar} +0 -0
  44. data/lib/template/bundled/{apache-maven-3.9.9/lib/maven-slf4j-provider-3.9.9.jar → apache-maven-3.9.12/lib/maven-slf4j-provider-3.9.12.jar} +0 -0
  45. data/lib/template/bundled/{apache-maven-3.9.9/lib/org.eclipse.sisu.inject-0.9.0.M3.jar → apache-maven-3.9.12/lib/org.eclipse.sisu.inject-0.9.0.M4.jar} +0 -0
  46. data/lib/template/bundled/{apache-maven-3.9.9/lib/org.eclipse.sisu.plexus-0.9.0.M3.jar → apache-maven-3.9.12/lib/org.eclipse.sisu.plexus-0.9.0.M4.jar} +0 -0
  47. data/lib/template/bundled/apache-maven-3.9.12/lib/plexus-component-annotations-2.2.0.jar +0 -0
  48. data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-interpolation-1.27.jar → apache-maven-3.9.12/lib/plexus-interpolation-1.29.jar} +0 -0
  49. data/lib/template/bundled/apache-maven-3.9.12/lib/plexus-sec-dispatcher.license +202 -0
  50. data/lib/template/bundled/apache-maven-3.9.12/lib/plexus-utils-3.6.0.jar +0 -0
  51. data/lib/template/bundled/apache-maven-3.9.12/lib/plexus-utils.license +202 -0
  52. data/lib/template/kit.spec +3 -3
  53. data/lib/template/package.spec +13 -10
  54. data/lib/tetra/constants.rb +10 -1
  55. data/lib/tetra/data/license_map.yml +124 -0
  56. data/lib/tetra/facades/ant.rb +4 -7
  57. data/lib/tetra/facades/bash.rb +28 -19
  58. data/lib/tetra/facades/git.rb +69 -34
  59. data/lib/tetra/facades/gradle.rb +3 -2
  60. data/lib/tetra/facades/mvn.rb +8 -8
  61. data/lib/tetra/facades/process_runner.rb +58 -37
  62. data/lib/tetra/facades/tar.rb +5 -4
  63. data/lib/tetra/facades/unzip.rb +5 -4
  64. data/lib/tetra/generatable.rb +4 -3
  65. data/lib/tetra/kit.rb +12 -6
  66. data/lib/tetra/license_mapper.rb +34 -0
  67. data/lib/tetra/logger.rb +7 -4
  68. data/lib/tetra/maven_website.rb +64 -27
  69. data/lib/tetra/packages/kit_package.rb +4 -4
  70. data/lib/tetra/packages/package.rb +47 -8
  71. data/lib/tetra/packages/scriptable.rb +12 -8
  72. data/lib/tetra/packages/speccable.rb +7 -1
  73. data/lib/tetra/pom.rb +38 -16
  74. data/lib/tetra/pom_getter.rb +55 -43
  75. data/lib/tetra/project.rb +14 -15
  76. data/lib/tetra/project_initer.rb +32 -20
  77. data/lib/tetra/ui/change_sources_subcommand.rb +13 -7
  78. data/lib/tetra/ui/dry_run_subcommand.rb +5 -3
  79. data/lib/tetra/ui/generate_all_subcommand.rb +1 -1
  80. data/lib/tetra/ui/generate_kit_subcommand.rb +2 -1
  81. data/lib/tetra/ui/generate_script_subcommand.rb +2 -3
  82. data/lib/tetra/ui/generate_spec_subcommand.rb +3 -2
  83. data/lib/tetra/ui/get_pom_subcommand.rb +17 -12
  84. data/lib/tetra/ui/init_subcommand.rb +12 -4
  85. data/lib/tetra/ui/main.rb +6 -1
  86. data/lib/tetra/ui/move_jars_to_kit_subcommand.rb +2 -2
  87. data/lib/tetra/ui/patch_subcommand.rb +1 -1
  88. data/lib/tetra/ui/subcommand.rb +37 -31
  89. data/lib/tetra/version.rb +2 -3
  90. data/lib/tetra/version_matcher.rb +62 -44
  91. data/lib/tetra.rb +10 -6
  92. metadata +184 -274
  93. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -26
  94. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -15
  95. data/.github/dependabot.yml +0 -24
  96. data/.github/workflows/action-lint.yml +0 -15
  97. data/.github/workflows/codeql-analysis.yml +0 -94
  98. data/.github/workflows/dependency-review.yml +0 -17
  99. data/.github/workflows/markdown.yml +0 -23
  100. data/.github/workflows/rubocop.yml +0 -51
  101. data/.github/workflows/test.yml +0 -62
  102. data/.gitignore +0 -27
  103. data/.markdownlint.yaml +0 -11
  104. data/.rubocop.yml +0 -35
  105. data/.rubocop_todo.yml +0 -438
  106. data/.sonarcloud.properties +0 -4
  107. data/Gemfile +0 -6
  108. data/Gemfile.lock +0 -228
  109. data/Rakefile +0 -9
  110. data/lib/template/bundled/apache-maven-3.9.9/LICENSE +0 -760
  111. data/lib/template/bundled/apache-maven-3.9.9/lib/commons-cli-1.8.0.jar +0 -0
  112. data/lib/template/bundled/apache-maven-3.9.9/lib/commons-codec-1.17.1.jar +0 -0
  113. data/lib/template/bundled/apache-maven-3.9.9/lib/failureaccess-1.0.2.jar +0 -0
  114. data/lib/template/bundled/apache-maven-3.9.9/lib/guava-33.2.1-jre.jar +0 -0
  115. data/lib/template/bundled/apache-maven-3.9.9/lib/guice-5.1.0.jar +0 -0
  116. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-embedder-3.9.9.jar +0 -0
  117. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-model-3.9.9.jar +0 -0
  118. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-plugin-api-3.9.9.jar +0 -0
  119. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-repository-metadata-3.9.9.jar +0 -0
  120. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-resolver-connector-basic-1.9.22.jar +0 -0
  121. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-resolver-transport-file-1.9.22.jar +0 -0
  122. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-resolver-transport-http-1.9.22.jar +0 -0
  123. data/lib/template/bundled/apache-maven-3.9.9/lib/maven-settings-3.9.9.jar +0 -0
  124. data/lib/template/bundled/apache-maven-3.9.9/lib/plexus-component-annotations-2.1.0.jar +0 -0
  125. data/lib/template/bundled/apache-maven-3.9.9/lib/plexus-utils-3.5.1.jar +0 -0
  126. data/lib/template/bundled/apache-maven-3.9.9/lib/plexus-xml-3.0.1.jar +0 -0
  127. data/lib/template/kit/.keep +0 -1
  128. data/lib/template/kit/jars/.keep +0 -1
  129. data/lib/template/packages/.keep +0 -1
  130. data/lib/template/src/.keep +0 -1
  131. data/spec/data/ant-super-simple-code/build/HW.class +0 -0
  132. data/spec/data/ant-super-simple-code/build/mypackage/HW.class +0 -0
  133. data/spec/data/ant-super-simple-code/build.xml +0 -133
  134. data/spec/data/ant-super-simple-code/dist/antsimple-20130618.jar +0 -0
  135. data/spec/data/ant-super-simple-code/lib/junit-4.11.jar +0 -0
  136. data/spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar +0 -0
  137. data/spec/data/ant-super-simple-code/src/mypackage/HW.java +0 -15
  138. data/spec/data/antlr/antlr-2.7.2.jar +0 -0
  139. data/spec/data/antlr/pom.xml +0 -6
  140. data/spec/data/commons-collections4-4.5.0-M2-src.tar.gz +0 -0
  141. data/spec/data/commons-collections4-4.5.0-M2-src.zip +0 -0
  142. data/spec/data/commons-logging/commons-logging-1.3.4.jar +0 -0
  143. data/spec/data/commons-logging/parent_pom.xml +0 -1995
  144. data/spec/data/commons-logging/pom.xml +0 -833
  145. data/spec/data/nailgun/nailgun-0.7.1.jar +0 -0
  146. data/spec/data/nailgun/pom.xml +0 -153
  147. data/spec/data/struts-apps/pom.xml +0 -1147
  148. data/spec/data/tomcat/pom.xml +0 -33
  149. data/spec/lib/coarse/dry_run_subcommand_spec.rb +0 -59
  150. data/spec/lib/coarse/generate_all_subcommand_spec.rb +0 -132
  151. data/spec/lib/coarse/generate_spec_subcommand_spec.rb +0 -30
  152. data/spec/lib/coarse/init_subcommand_spec.rb +0 -101
  153. data/spec/lib/coarse/main_spec.rb +0 -21
  154. data/spec/lib/fine/ant_spec.rb +0 -25
  155. data/spec/lib/fine/git_spec.rb +0 -181
  156. data/spec/lib/fine/kit_package_spec.rb +0 -31
  157. data/spec/lib/fine/kit_spec.rb +0 -27
  158. data/spec/lib/fine/maven_website_spec.rb +0 -61
  159. data/spec/lib/fine/mvn_spec.rb +0 -27
  160. data/spec/lib/fine/package_spec.rb +0 -68
  161. data/spec/lib/fine/pom_getter_spec.rb +0 -36
  162. data/spec/lib/fine/pom_spec.rb +0 -98
  163. data/spec/lib/fine/project_spec.rb +0 -234
  164. data/spec/lib/fine/scriptable_spec.rb +0 -56
  165. data/spec/lib/fine/speccable_spec.rb +0 -93
  166. data/spec/lib/fine/tar_spec.rb +0 -22
  167. data/spec/lib/fine/unzip_spec.rb +0 -22
  168. data/spec/lib/fine/version_matcher_spec.rb +0 -64
  169. data/spec/spec_helper.rb +0 -90
  170. data/tetra.gemspec +0 -44
  171. data/utils/delete_nonet_user.sh +0 -8
  172. data/utils/setup_nonet_user.sh +0 -8
  173. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/README.txt +0 -0
  174. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/m2.conf +0 -0
  175. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/mvnDebug +0 -0
  176. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/mvnDebug.cmd +0 -0
  177. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/bin/mvnyjp +0 -0
  178. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/boot/plexus-classworlds.license +0 -0
  179. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/conf/logging/simplelogger.properties +0 -0
  180. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/conf/settings.xml +0 -0
  181. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/conf/toolchains.xml +0 -0
  182. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/aopalliance-1.0.jar +0 -0
  183. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/aopalliance.license +0 -0
  184. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/commons-cli.license +0 -0
  185. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/commons-codec.license +0 -0
  186. /data/lib/template/bundled/{apache-maven-3.9.9/lib/failureaccess.license → apache-maven-3.9.12/lib/error_prone_annotations.license} +0 -0
  187. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/ext/README.txt +0 -0
  188. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/ext/hazelcast/README.txt +0 -0
  189. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/ext/redisson/README.txt +0 -0
  190. /data/lib/template/bundled/{apache-maven-3.9.9/lib/guava.license → apache-maven-3.9.12/lib/failureaccess.license} +0 -0
  191. /data/lib/template/bundled/{apache-maven-3.9.9/lib/guice.license → apache-maven-3.9.12/lib/gson.license} +0 -0
  192. /data/lib/template/bundled/{apache-maven-3.9.9/lib/httpclient.license → apache-maven-3.9.12/lib/guava.license} +0 -0
  193. /data/lib/template/bundled/{apache-maven-3.9.9/lib/httpcore.license → apache-maven-3.9.12/lib/guice.license} +0 -0
  194. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/httpclient-4.5.14.jar +0 -0
  195. /data/lib/template/bundled/{apache-maven-3.9.9/lib/jansi.license → apache-maven-3.9.12/lib/httpclient.license} +0 -0
  196. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/httpcore-4.4.16.jar +0 -0
  197. /data/lib/template/bundled/{apache-maven-3.9.9/lib/javax.inject.license → apache-maven-3.9.12/lib/httpcore.license} +0 -0
  198. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/jansi-native/README.txt +0 -0
  199. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/jansi-native/Windows/x86/jansi.dll +0 -0
  200. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/jansi-native/Windows/x86_64/jansi.dll +0 -0
  201. /data/lib/template/bundled/{apache-maven-3.9.9/lib/jcl-over-slf4j.license → apache-maven-3.9.12/lib/jansi.license} +0 -0
  202. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/javax.annotation-api-1.3.2.jar +0 -0
  203. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/javax.annotation-api.license +0 -0
  204. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/javax.inject-1.jar +0 -0
  205. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-cipher.license → apache-maven-3.9.12/lib/javax.inject.license} +0 -0
  206. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/jcl-over-slf4j-1.7.36.jar +0 -0
  207. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-component-annotations.license → apache-maven-3.9.12/lib/jcl-over-slf4j.license} +0 -0
  208. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-interpolation.license → apache-maven-3.9.12/lib/jspecify.license} +0 -0
  209. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/maven-shared-utils-3.4.2.jar +0 -0
  210. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/org.eclipse.sisu.inject.license +0 -0
  211. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/org.eclipse.sisu.plexus.license +0 -0
  212. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/plexus-cipher-2.0.jar +0 -0
  213. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-sec-dispatcher.license → apache-maven-3.9.12/lib/plexus-cipher.license} +0 -0
  214. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-utils.license → apache-maven-3.9.12/lib/plexus-component-annotations.license} +0 -0
  215. /data/lib/template/bundled/{apache-maven-3.9.9/lib/plexus-xml.license → apache-maven-3.9.12/lib/plexus-interpolation.license} +0 -0
  216. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/plexus-sec-dispatcher-2.0.jar +0 -0
  217. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/slf4j-api-1.7.36.jar +0 -0
  218. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/slf4j-api.license +0 -0
  219. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/wagon-file-3.5.3.jar +0 -0
  220. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/wagon-http-3.5.3.jar +0 -0
  221. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/wagon-http-shared-3.5.3.jar +0 -0
  222. /data/lib/template/bundled/{apache-maven-3.9.9 → apache-maven-3.9.12}/lib/wagon-provider-api-3.5.3.jar +0 -0
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require "erb"
4
4
 
@@ -7,12 +7,13 @@ module Tetra
7
7
  module Generatable
8
8
  # returns the template path
9
9
  def template_path
10
- File.join(File.dirname(__FILE__), "..", "template")
10
+ File.join(__dir__, "..", "template")
11
11
  end
12
12
 
13
13
  # generates content from an ERB template and an object binding
14
14
  def generate(template_name, object_binding)
15
- erb = ERB.new(File.read(File.join(template_path, template_name)), trim_mode: "<>")
15
+ template_file = File.join(template_path, template_name)
16
+ erb = ERB.new(File.read(template_file), trim_mode: "<>")
16
17
  erb.result(object_binding)
17
18
  end
18
19
  end
data/lib/tetra/kit.rb CHANGED
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # encapsulates a Tetra kit directory
@@ -13,12 +13,18 @@ module Tetra
13
13
  # returns nil if executable cannot be found
14
14
  def find_executable(name)
15
15
  @project.from_directory do
16
- Find.find("kit") do |path|
17
- next unless path =~ %r{(.*bin)/#{name}$} && File.executable?(path)
18
- result = Regexp.last_match[1]
16
+ # The pattern `**/*bin/#{name}` matches:
17
+ # - kit/bin/mvn
18
+ # - kit/usr/local/bin/ant
19
+ # - kit/sbin/service (matches your original regex .*bin)
20
+ Dir.glob(File.join("kit", "**", "*bin", name)).each do |path|
21
+ next unless File.executable?(path)
19
22
 
20
- log.debug("found #{name} executable in #{result}")
21
- return result
23
+ # Your original regex captured the directory part (.*bin)
24
+ dir = File.dirname(path)
25
+
26
+ log.debug("found #{name} executable in #{dir}")
27
+ return dir
22
28
  end
23
29
  end
24
30
 
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tetra
4
+ # Handles mapping raw license names to SPDX identifiers
5
+ class LicenseMapper
6
+ class << self
7
+ def map(raw_name)
8
+ return "unknown" if raw_name.nil? || raw_name.strip.empty?
9
+
10
+ name = raw_name.strip
11
+ mapping[name] || name
12
+ end
13
+
14
+ def reset!
15
+ @mapping = nil
16
+ end
17
+
18
+ private
19
+
20
+ def mapping
21
+ @mapping ||= begin
22
+ load_mapping
23
+ rescue Errno::ENOENT, Psych::SyntaxError, Psych::DisallowedClass, IOError => e
24
+ warn "Warning: failed to load license mapping from #{Tetra::LICENSE_MAP_PATH}: #{e.class}: #{e.message}"
25
+ {}
26
+ end
27
+ end
28
+
29
+ def load_mapping
30
+ YAML.safe_load_file(Tetra::LICENSE_MAP_PATH) || {}
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/tetra/logger.rb CHANGED
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # configures logging for this application
@@ -6,14 +6,17 @@ module Tetra
6
6
  include Singleton
7
7
  extend Forwardable
8
8
 
9
- def_delegators :@logger, :debug, :info, :warn, :error, :fatal, :level=
9
+ def_delegators :@logger, :debug, :info, :warn, :error, :fatal, :level, :level=, :formatter=
10
10
 
11
11
  def initialize
12
- @logger = ::Logger.new(STDERR)
12
+ @logger = ::Logger.new($stderr)
13
+
13
14
  @logger.datetime_format = "%Y-%m-%d %H:%M "
14
15
  @logger.level = ::Logger::ERROR
16
+
15
17
  @logger.formatter = proc do |severity, _datetime, _progname, msg|
16
- "#{severity.chars.first}: #{msg}\n"
18
+ # PERFORMANCE: severity[0] is faster than severity.chars.first (no array allocation)
19
+ "#{severity[0]}: #{msg}\n"
17
20
  end
18
21
  end
19
22
  end
@@ -1,64 +1,101 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "json"
2
6
 
3
7
  module Tetra
4
- # Facade to search.maven.org
8
+ # Facade to search.maven.org (and central.sonatype.com)
5
9
  class MavenWebsite
6
10
  include Logging
7
11
 
8
- # returns a search result object from search.maven.com
9
- # searching by a jar sha1 hash
10
- # see output format at https://search.maven.org/#api
12
+ # API Constants
13
+ SEARCH_API = "https://search.maven.org/solrsearch/select".freeze
14
+ DOWNLOAD_API = "https://repo1.maven.org/maven2".freeze
15
+
11
16
  def search_by_sha1(sha1)
12
17
  search(q: "1:\"#{sha1}\"")
13
18
  end
14
19
 
15
- # returns a search result object from search.maven.com
16
- # searching by keyword (name)
17
- # see output format at https://search.maven.org/#api
18
20
  def search_by_name(name)
19
21
  search(q: name)
20
22
  end
21
23
 
22
- # returns a search result object from search.maven.com
23
- # searching by Maven's group id and artifact id
24
- # see output format at https://search.maven.org/#api
25
24
  def search_by_group_id_and_artifact_id(group_id, artifact_id)
26
25
  search(q: "g:\"#{group_id}\" AND a:\"#{artifact_id}\"", core: "gav")
27
26
  end
28
27
 
29
- # returns a search result object from search.maven.com
30
- # searching by Maven's id (group id, artifact id and version)
31
- # see output format at https://search.maven.org/#api
32
28
  def search_by_maven_id(group_id, artifact_id, version)
33
29
  search(q: "g:\"#{group_id}\" AND a:\"#{artifact_id}\" AND v:\"#{version}\"")
34
30
  end
35
31
 
36
- # returns a search result object from search.maven.com
37
- # see input and output format at https://search.maven.org/#api
38
32
  def search(params)
39
- response = get("https://search.maven.org/solrsearch/select?", params.merge("rows" => "100", "wt" => "json"))
40
- json = JSON.parse(response.to_s)
33
+ # Merge default API parameters
34
+ full_params = params.merge("rows" => "100", "wt" => "json")
35
+ response_body = fetch(SEARCH_API, full_params)
36
+
37
+ json = JSON.parse(response_body)
41
38
  json["response"]["docs"]
42
39
  end
43
40
 
44
- # returns a Maven's triple (artifactId, groupId, version)
45
- # from a result object
46
41
  def get_maven_id_from(result)
47
42
  [result["g"], result["a"], result["v"]]
48
43
  end
49
44
 
50
- # downloads a POM from a search.maven.com search result
51
45
  def download_pom(group_id, artifact_id, version)
52
- path = "#{group_id.gsub('.', '/')}/#{artifact_id}/#{version}/#{artifact_id}-#{version}.pom"
46
+ # Use tr instead of gsub for performance (standard Ruby optimization)
47
+ group_path = group_id.tr(".", "/")
48
+ path = "#{group_path}/#{artifact_id}/#{version}/#{artifact_id}-#{version}.pom"
49
+
53
50
  log.debug("downloading #{path}...")
54
- get("https://repo1.maven.org/maven2/#{path}", {}).to_s
51
+
52
+ # We pass empty params because the path contains everything
53
+ url = "#{DOWNLOAD_API}/#{path}"
54
+ fetch(url)
55
55
  end
56
56
 
57
- def get(url, params)
58
- response = Net::HTTP.get_response(URI.parse(url + URI.encode_www_form(params)))
59
- fail NotFoundOnMavenWebsiteError if response.code == "404"
57
+ private
58
+
59
+ # A robust HTTP fetcher with Retries, Timeouts, and Redirect handling
60
+ def fetch(url_str, params = {}, limit = 5)
61
+ raise ArgumentError, "HTTP redirect too deep" if limit.zero?
62
+
63
+ uri = URI(url_str)
64
+ uri.query = URI.encode_www_form(params) unless params.empty?
65
+
66
+ retries = 0
67
+ begin
68
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
69
+ http.open_timeout = 10 # Wait 10s for connection
70
+ http.read_timeout = 30 # Wait 30s for data
71
+
72
+ request = Net::HTTP::Get.new(uri)
73
+ http.request(request)
74
+ end
60
75
 
61
- response.body
76
+ case response
77
+ when Net::HTTPSuccess
78
+ response.body
79
+ when Net::HTTPRedirection
80
+ location = response["location"]
81
+ log.info("Redirected to #{location}")
82
+ # Recursive call to follow redirect (params are usually part of the new URL)
83
+ fetch(location, {}, limit - 1)
84
+ when Net::HTTPNotFound
85
+ fail NotFoundOnMavenWebsiteError
86
+ else
87
+ fail "Remote error: #{response.code} #{response.message}"
88
+ end
89
+ rescue Net::OpenTimeout, Net::ReadTimeout, SocketError, Errno::ECONNRESET => e
90
+ if (retries += 1) <= 3
91
+ log.warn("Network error: #{e.class} - #{e.message}. Retrying (#{retries}/3)...")
92
+ sleep(1) # Backoff before retry
93
+ retry
94
+ else
95
+ log.error("Failed to fetch #{url_str} after 3 retries")
96
+ raise e
97
+ end
98
+ end
62
99
  end
63
100
  end
64
101
 
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # a packaged set of binary build-time dependencies
@@ -7,18 +7,18 @@ module Tetra
7
7
  include Speccable
8
8
 
9
9
  attr_reader :name
10
+
11
+ # Delegation allows accessing project properties directly
10
12
  def_delegator :@project, :version
11
13
  def_delegator :@project, :name, :project_name
12
14
 
13
15
  def initialize(project)
14
16
  @project = project
15
-
16
17
  @name = "#{project.name}-kit"
17
18
  end
18
19
 
19
20
  def to_spec
20
- _to_spec(@project, name, "kit.spec",
21
- @project.packages_dir)
21
+ _to_spec(@project, name, "kit.spec", @project.packages_dir)
22
22
  end
23
23
  end
24
24
  end
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # represents a Java project packaged in tetra
@@ -13,7 +13,6 @@ module Tetra
13
13
  def_delegator :@project, :src_archive
14
14
  def_delegator :@kit, :name, :kit_name
15
15
  def_delegator :@kit, :version, :kit_version
16
- def_delegator :@pom, :license_name, :license
17
16
  def_delegator :@pom, :url
18
17
  def_delegator :@pom, :group_id
19
18
  def_delegator :@pom, :version
@@ -27,6 +26,37 @@ module Tetra
27
26
  @patches = patches.map { |f| File.basename(f) }
28
27
  end
29
28
 
29
+ def license
30
+ Tetra::LicenseMapper.map(@pom.license_name)
31
+ end
32
+
33
+ # Scans for license files in the src/ directory (Issue #12)
34
+ def license_files
35
+ @project.from_directory do
36
+ # Tetra unpacks sources into 'src/', so we search there.
37
+ # We manually check filenames with Ruby regex to ensure reliable
38
+ # case-insensitive matching across different OS filesystems (Linux vs macOS).
39
+
40
+ candidates = Dir.glob("src/*")
41
+
42
+ files = candidates.select do |file|
43
+ next unless File.file?(file)
44
+
45
+ basename = File.basename(file)
46
+
47
+ # Match standard license filenames (case insensitive)
48
+ # Equivalent to: LICENSE*, COPYING*, COPYRIGHT*
49
+ basename.match?(/^LICENSE/i) ||
50
+ basename.match?(/^COPYING/i) ||
51
+ basename.match?(/^COPYRIGHT/i)
52
+ end
53
+
54
+ # Return just the filenames (e.g. "LICENSE") so the spec file
55
+ # (which runs inside src/ due to %setup -n src) can reference them directly.
56
+ files.map { |f| File.basename(f) }.uniq.sort
57
+ end
58
+ end
59
+
30
60
  def artifact_ids
31
61
  @pom.modules.any? ? @pom.modules : [@pom.artifact_id]
32
62
  end
@@ -49,12 +79,21 @@ module Tetra
49
79
  end
50
80
 
51
81
  def cleanup_description(raw, max_length)
52
- raw
53
- .gsub(/[\s]+/, " ")
54
- .strip
55
- .slice(0..max_length - 1)
56
- .sub(/\s\w+$/, "")
57
- .sub(/\.+$/, "")
82
+ return "" if raw.nil? || raw.strip.empty?
83
+
84
+ # Normalize spaces (collapse multiple spaces/newlines to single space)
85
+ clean = raw.gsub(/\s+/, " ").strip
86
+
87
+ # Truncate to max_length
88
+ clean = clean[0, max_length]
89
+
90
+ # Remove the last word if it looks cut off (ends in letters, not punctuation)
91
+ clean = clean.sub(/\s\w+\z/, "")
92
+
93
+ # Remove ALL trailing dots efficiently
94
+ clean = clean.chomp(".") while clean.end_with?(".")
95
+
96
+ clean
58
97
  end
59
98
 
60
99
  def to_spec
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # generates a package build script from bash_history
@@ -11,13 +11,14 @@ module Tetra
11
11
  "set -xe",
12
12
  "PROJECT_PREFIX=`readlink -e .`",
13
13
  "cd #{project.latest_dry_run_directory}"
14
- ] + aliases(project) + project.build_script_lines
14
+ ] + generate_aliases(project) + project.build_script_lines
15
15
 
16
16
  new_content = script_lines.join("\n") + "\n"
17
17
 
18
18
  result_dir = File.join(project.packages_dir, project.name)
19
19
  FileUtils.mkdir_p(result_dir)
20
20
  result_path = File.join(result_dir, "build.sh")
21
+
21
22
  conflict_count = project.merge_new_content(new_content, result_path, "Build script generated",
22
23
  "script")
23
24
 
@@ -26,22 +27,25 @@ module Tetra
26
27
  end
27
28
 
28
29
  # setup aliases for adjusted versions of the packaging tools
29
- def aliases(project)
30
+ def generate_aliases(project)
30
31
  kit = Tetra::Kit.new(project)
32
+ cmds = []
31
33
 
32
- aliases = []
33
34
  ant_path = kit.find_executable("ant")
34
35
  ant_commandline = Tetra::Ant.commandline("$PROJECT_PREFIX", ant_path)
35
- aliases << "alias ant='#{ant_commandline}'"
36
+ cmds << "alias ant='#{ant_commandline}'"
36
37
 
37
38
  mvn_path = kit.find_executable("mvn")
38
39
  mvn_commandline = Tetra::Mvn.commandline("$PROJECT_PREFIX", mvn_path)
39
- aliases << "alias mvn='#{mvn_commandline} -o'"
40
+ cmds << "alias mvn='#{mvn_commandline} -o'"
40
41
 
41
42
  gradle_commandline = Tetra::Gradle.commandline("$PROJECT_PREFIX")
42
- aliases << "alias gradlew='#{gradle_commandline} --offline'"
43
+ cmds << "alias gradlew='#{gradle_commandline} --offline'"
43
44
 
44
- aliases
45
+ cmds
45
46
  end
47
+
48
+ # Alias for backward compatibility if other classes call 'aliases'
49
+ alias aliases generate_aliases
46
50
  end
47
51
  end
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # adds methods to generate a spec file from a package object
@@ -13,14 +13,20 @@ module Tetra
13
13
  project.from_directory do
14
14
  spec_name = "#{name}.spec"
15
15
  spec_dir = File.join(destination_dir, name)
16
+
16
17
  FileUtils.mkdir_p(spec_dir)
17
18
 
18
19
  spec_path = File.join(spec_dir, spec_name)
19
20
 
21
+ # Generate content using the template and current binding
20
22
  new_content = generate(template_spec_name, binding)
23
+
21
24
  label = "Spec for #{name} generated"
25
+
26
+ # Merge content (handles git operations for conflict resolution)
22
27
  conflict_count = project.merge_new_content(new_content, spec_path,
23
28
  label, "#{name}-spec")
29
+
24
30
  [spec_path, conflict_count]
25
31
  end
26
32
  end
data/lib/tetra/pom.rb CHANGED
@@ -1,59 +1,81 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # encapsulates a pom.xml file
5
5
  class Pom
6
6
  def initialize(filename)
7
- content = File.open(filename).read if filename && File.file?(filename)
7
+ # ROBUSTNESS: Handle missing file gracefully by initializing empty content
8
+ content = if filename && File.file?(filename)
9
+ File.read(filename)
10
+ else
11
+ "<project></project>"
12
+ end
8
13
  @doc = REXML::Document.new(content)
9
14
  end
10
15
 
11
16
  def group_id
12
- @doc.text("project/groupId") || ""
17
+ xpath_text("project/groupId")
13
18
  end
14
19
 
15
20
  def artifact_id
16
- @doc.text("project/artifactId") || ""
21
+ xpath_text("project/artifactId")
17
22
  end
18
23
 
19
24
  def name
20
- @doc.text("project/name") || ""
25
+ xpath_text("project/name")
21
26
  end
22
27
 
23
28
  def version
24
- @doc.text("project/version") || ""
29
+ xpath_text("project/version")
25
30
  end
26
31
 
27
32
  def description
28
- @doc.text("project/description") || ""
33
+ xpath_text("project/description")
29
34
  end
30
35
 
31
36
  def url
32
- @doc.text("project/url") || ""
37
+ xpath_text("project/url")
33
38
  end
34
39
 
35
40
  def license_name
36
- @doc.text("project/licenses/license/name") || ""
41
+ xpath_text("project/licenses/license/name")
37
42
  end
38
43
 
39
44
  def runtime_dependency_ids
40
- @doc.get_elements("project/dependencies/dependency[\
41
- not(optional='true') and not(scope='provided') and not(scope='test') and not(scope='system')\
42
- ]").map do |element|
43
- [element.text("groupId"), element.text("artifactId"), element.text("version")]
45
+ # CLEANUP: Use standard multi-line string for complex XPath
46
+ xpath = "project/dependencies/dependency[" \
47
+ "not(optional='true') and " \
48
+ "not(scope='provided') and " \
49
+ "not(scope='test') and " \
50
+ "not(scope='system')]"
51
+
52
+ REXML::XPath.match(@doc, xpath).map do |element|
53
+ [
54
+ element.elements["groupId"]&.text,
55
+ element.elements["artifactId"]&.text,
56
+ element.elements["version"]&.text
57
+ ]
44
58
  end
45
59
  end
46
60
 
47
61
  def modules
48
- @doc.get_elements("project/modules/module").map(&:text)
62
+ REXML::XPath.match(@doc, "project/modules/module").map(&:text)
49
63
  end
50
64
 
51
65
  def scm_connection
52
- @doc.text("project/scm/connection") || ""
66
+ xpath_text("project/scm/connection")
53
67
  end
54
68
 
55
69
  def scm_url
56
- @doc.text("project/scm/url") || ""
70
+ xpath_text("project/scm/url")
71
+ end
72
+
73
+ private
74
+
75
+ # HELPER: REXML does not support doc.text("xpath"), so we wrap the logic here.
76
+ def xpath_text(path)
77
+ # Safe navigation (&.) returns nil if node not found; || "" ensures String return
78
+ REXML::XPath.first(@doc, path)&.text&.strip || ""
57
79
  end
58
80
  end
59
81
  end