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
@@ -0,0 +1,124 @@
1
+ # Mappings of Raw Maven License Names -> SPDX Identifiers
2
+ # Based on https://spdx.org/licenses/ and openSUSE/Fedora standards
3
+
4
+ # --- Apache Licenses ---
5
+ "The Apache Software License, Version 2.0": "Apache-2.0"
6
+ "Apache License, Version 2.0": "Apache-2.0"
7
+ "Apache License Version 2.0": "Apache-2.0"
8
+ "Apache 2.0": "Apache-2.0"
9
+ "Apache License 2.0": "Apache-2.0"
10
+ "AL 2.0": "Apache-2.0"
11
+ "Apache Software License - Version 2.0": "Apache-2.0"
12
+ "The Apache License, Version 2.0": "Apache-2.0"
13
+ "Apache-2.0": "Apache-2.0"
14
+
15
+ "Apache License, Version 1.1": "Apache-1.1"
16
+ "The Apache Software License, Version 1.1": "Apache-1.1"
17
+ "Apache 1.1": "Apache-1.1"
18
+
19
+ "Apache License, Version 1.0": "Apache-1.0"
20
+
21
+ # --- MIT Licenses ---
22
+ "The MIT License": "MIT"
23
+ "MIT License": "MIT"
24
+ "MIT": "MIT"
25
+ "MIT license": "MIT"
26
+ "The MIT License (MIT)": "MIT"
27
+
28
+ # --- Eclipse Public Licenses ---
29
+ "Eclipse Public License 1.0": "EPL-1.0"
30
+ "Eclipse Public License - v 1.0": "EPL-1.0"
31
+ "Eclipse Public License, Version 1.0": "EPL-1.0"
32
+ "EPL 1.0": "EPL-1.0"
33
+
34
+ "Eclipse Public License 2.0": "EPL-2.0"
35
+ "Eclipse Public License - v 2.0": "EPL-2.0"
36
+ "EPL 2.0": "EPL-2.0"
37
+
38
+ # --- GPL (General Public License) ---
39
+ "GNU General Public License, version 2": "GPL-2.0-only"
40
+ "GNU General Public License, Version 2": "GPL-2.0-only"
41
+ "GPL 2.0": "GPL-2.0-only"
42
+ "GPLv2": "GPL-2.0-only"
43
+ "The GNU General Public License, Version 2": "GPL-2.0-only"
44
+
45
+ "GNU General Public License, version 2 (GPLv2)": "GPL-2.0-only"
46
+ "GNU General Public License, version 3": "GPL-3.0-only"
47
+ "GPL 3.0": "GPL-3.0-only"
48
+ "GPLv3": "GPL-3.0-only"
49
+
50
+ # --- LGPL (Lesser General Public License) ---
51
+ "GNU Lesser General Public License": "LGPL-2.1-only"
52
+ "GNU Lesser General Public License, version 2.1": "LGPL-2.1-only"
53
+ "LGPL 2.1": "LGPL-2.1-only"
54
+ "LGPLv2.1": "LGPL-2.1-only"
55
+ "The GNU Lesser General Public License, Version 2.1": "LGPL-2.1-only"
56
+
57
+ "GNU Lesser General Public License, version 3": "LGPL-3.0-only"
58
+ "LGPL 3.0": "LGPL-3.0-only"
59
+ "LGPLv3": "LGPL-3.0-only"
60
+
61
+ # --- BSD Licenses ---
62
+ "The BSD License": "BSD-2-Clause" # Ambiguous, but often 2-clause in modern Java
63
+ "BSD License": "BSD-2-Clause"
64
+ "BSD-2-Clause": "BSD-2-Clause"
65
+ "Two-clause BSD license": "BSD-2-Clause"
66
+ "The BSD 2-Clause License": "BSD-2-Clause"
67
+
68
+ "New BSD License": "BSD-3-Clause"
69
+ "BSD 3-Clause": "BSD-3-Clause"
70
+ "BSD 3-Clause License": "BSD-3-Clause"
71
+ "The BSD 3-Clause License": "BSD-3-Clause"
72
+ "Revised BSD License": "BSD-3-Clause"
73
+ "Modified BSD License": "BSD-3-Clause"
74
+
75
+ "BSD 0-Clause": "0BSD"
76
+ "0BSD": "0BSD"
77
+
78
+ # --- CDDL (Common Development and Distribution License) ---
79
+ "Common Development and Distribution License": "CDDL-1.0"
80
+ "CDDL 1.0": "CDDL-1.0"
81
+ "CDDL-1.0": "CDDL-1.0"
82
+ "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0": "CDDL-1.0"
83
+
84
+ "Common Development and Distribution License 1.1": "CDDL-1.1"
85
+ "CDDL 1.1": "CDDL-1.1"
86
+
87
+ # --- MPL (Mozilla Public License) ---
88
+ "Mozilla Public License Version 1.1": "MPL-1.1"
89
+ "MPL 1.1": "MPL-1.1"
90
+
91
+ "Mozilla Public License Version 2.0": "MPL-2.0"
92
+ "MPL 2.0": "MPL-2.0"
93
+ "The Mozilla Public License, Version 2.0": "MPL-2.0"
94
+
95
+ # --- ISC License ---
96
+ "ISC License": "ISC"
97
+ "The ISC License": "ISC"
98
+
99
+ # --- Creative Commons ---
100
+ "Creative Commons Zero v1.0 Universal": "CC0-1.0"
101
+ "CC0 1.0 Universal": "CC0-1.0"
102
+ "Public Domain": "CC0-1.0" # Approximation for Public Domain in SPDX
103
+
104
+ "Creative Commons Attribution 3.0": "CC-BY-3.0"
105
+ "CC BY 3.0": "CC-BY-3.0"
106
+
107
+ "Creative Commons Attribution 4.0": "CC-BY-4.0"
108
+ "CC BY 4.0": "CC-BY-4.0"
109
+
110
+ # --- Other Common Java Licenses ---
111
+ "The JSON License": "JSON"
112
+ "JSON": "JSON"
113
+
114
+ "Unlicense": "Unlicense"
115
+ "The Unlicense": "Unlicense"
116
+
117
+ "WTFPL": "WTFPL"
118
+ "Do What The F*ck You Want To Public License": "WTFPL"
119
+
120
+ "PostgreSQL License": "PostgreSQL"
121
+ "The PostgreSQL License": "PostgreSQL"
122
+
123
+ "Zlib License": "Zlib"
124
+ "The zlib/libpng License": "Zlib"
@@ -1,15 +1,12 @@
1
- # encoding: UTF-8
2
-
1
+ # frozen_string_literal: true
3
2
  module Tetra
4
3
  # encapsulates tetra-specific Ant commandline options
5
4
  class Ant
6
5
  # returns a command line for running Ant
7
6
  def self.commandline(project_path, ant_path)
8
- if ant_path
9
- File.join(project_path, ant_path, "ant")
10
- else
11
- "ant" # use system-provided executable
12
- end
7
+ return "ant" unless ant_path
8
+
9
+ File.join(project_path, ant_path, "ant")
13
10
  end
14
11
  end
15
12
  end
@@ -1,5 +1,4 @@
1
- # encoding: UTF-8
2
-
1
+ # frozen_string_literal: true
3
2
  module Tetra
4
3
  # runs Bash with tetra-specific options
5
4
  class Bash
@@ -16,32 +15,44 @@ module Tetra
16
15
  Tempfile.open("tetra-history") do |history_file|
17
16
  Tempfile.open("tetra-bashrc") do |bashrc_file|
18
17
  kit = Tetra::Kit.new(@project)
18
+
19
19
  ant_path = kit.find_executable("ant")
20
- ant_in_kit = ant_path != nil
21
20
  ant_commandline = Tetra::Ant.commandline(@project.full_path, ant_path)
22
21
 
23
22
  mvn_path = kit.find_executable("mvn")
24
- mvn_in_kit = mvn_path != nil
25
23
  mvn_commandline = Tetra::Mvn.commandline(@project.full_path, mvn_path)
26
24
 
27
25
  gradle_commandline = Tetra::Gradle.commandline(@project.full_path)
28
26
 
29
- bashrc_content = Bashrc.new(history_file.path, ant_in_kit, ant_commandline, mvn_in_kit, mvn_commandline,
30
- gradle_commandline).to_s
31
- log.debug "writing bashrc file: #{bashrc_file.path}"
32
- log.debug bashrc_content
27
+ bashrc_content = Bashrc.new(
28
+ history_file: history_file.path,
29
+ ant_in_kit: !ant_path.nil?,
30
+ ant_commandline: ant_commandline,
31
+ mvn_in_kit: !mvn_path.nil?,
32
+ mvn_commandline: mvn_commandline,
33
+ gradle_commandline: gradle_commandline
34
+ ).to_s
35
+
36
+ log.debug("writing bashrc file: #{bashrc_file.path}")
37
+ log.debug(bashrc_content)
33
38
 
34
39
  bashrc_file.write(bashrc_content)
35
40
  bashrc_file.flush
36
41
 
37
42
  if command
38
- run("bash --rcfile #{bashrc_file.path} -i -c '#{command}'")
43
+ # SECURITY: Use array execution to prevent shell injection via 'command'
44
+ # The 'bash -c' flag normally takes a single string, so we must be careful.
45
+ # Ideally, passing it as a single array element ["bash", ..., "-c", command]
46
+ # is handled safely by ProcessRunner if it uses exec/system/spawn.
47
+ run(["bash", "--rcfile", bashrc_file.path, "-i", "-c", command])
39
48
  [command]
40
49
  else
41
- run_interactive("bash --rcfile #{bashrc_file.path} -i")
50
+ # Interactive mode
51
+ run_interactive(["bash", "--rcfile", bashrc_file.path, "-i"])
52
+
42
53
  history = File.read(history_file)
43
- log.debug "history contents:"
44
- log.debug history
54
+ log.debug("history contents:")
55
+ log.debug(history)
45
56
 
46
57
  history.split("\n").map(&:strip)
47
58
  end
@@ -54,14 +65,12 @@ module Tetra
54
65
  class Bashrc
55
66
  include Tetra::Generatable
56
67
 
57
- attr_reader :history_file
58
- attr_reader :ant_in_kit
59
- attr_reader :ant_commandline
60
- attr_reader :mvn_in_kit
61
- attr_reader :mvn_commandline
62
- attr_reader :gradle_commandline
68
+ # Expose attributes for the ERB binding
69
+ attr_reader :history_file, :ant_in_kit, :ant_commandline,
70
+ :mvn_in_kit, :mvn_commandline, :gradle_commandline
63
71
 
64
- def initialize(history_file, ant_in_kit, ant_commandline, mvn_in_kit, mvn_commandline, gradle_commandline)
72
+ def initialize(history_file:, ant_in_kit:, ant_commandline:,
73
+ mvn_in_kit:, mvn_commandline:, gradle_commandline:)
65
74
  @history_file = history_file
66
75
  @ant_in_kit = ant_in_kit
67
76
  @ant_commandline = ant_commandline
@@ -1,4 +1,6 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
2
4
 
3
5
  module Tetra
4
6
  # facade to git, currently implemented with calls to the git command
@@ -15,10 +17,10 @@ module Tetra
15
17
  # inits a repo
16
18
  def init
17
19
  Dir.chdir(@directory) do
18
- if Dir.exist?(".git") == false
19
- run("git init")
20
- else
20
+ if Dir.exist?(".git")
21
21
  fail GitAlreadyInitedError
22
+ else
23
+ git_cmd("init")
22
24
  end
23
25
  end
24
26
  end
@@ -28,8 +30,8 @@ module Tetra
28
30
  # returns nil if such commit does not exist
29
31
  def latest_id(comment_prefix)
30
32
  Dir.chdir(@directory) do
31
- result = run("git rev-list --max-count=1 --grep=\"#{comment_prefix}\" --fixed-strings HEAD")
32
- result.strip if result != ""
33
+ result = git_cmd("rev-list", "--max-count=1", "--grep", comment_prefix, "--fixed-strings", "HEAD")
34
+ result.strip unless result.empty?
33
35
  end
34
36
  end
35
37
 
@@ -39,7 +41,7 @@ module Tetra
39
41
  def latest_comment(comment_prefix)
40
42
  Dir.chdir(@directory) do
41
43
  id = latest_id(comment_prefix)
42
- run("git rev-list --max-count=1 --format=%B #{id}") unless id.nil?
44
+ git_cmd("log", "-1", "--format=%B", id) if id
43
45
  end
44
46
  end
45
47
 
@@ -50,11 +52,11 @@ module Tetra
50
52
  log.debug "committing with message: #{message}"
51
53
 
52
54
  Dir.chdir(@directory) do
53
- directories.each do |directory|
54
- run("git rm -r --cached --ignore-unmatch #{directory}")
55
- run("git add #{directory}")
55
+ if directories.any?
56
+ git_cmd("rm", "-r", "--cached", "--ignore-unmatch", *directories)
57
+ git_cmd("add", *directories)
56
58
  end
57
- run("git commit --allow-empty -F -", false, message)
59
+ git_cmd_with_stdin(message, "commit", "--allow-empty", "-F", "-")
58
60
  end
59
61
  end
60
62
 
@@ -62,8 +64,8 @@ module Tetra
62
64
  def commit_file(path, message)
63
65
  Dir.chdir(@directory) do
64
66
  log.debug "committing path #{path} with message: #{message}"
65
- run("git add #{path}")
66
- run("git commit --allow-empty -F -", false, message)
67
+ git_cmd("add", path)
68
+ git_cmd_with_stdin(message, "commit", "--allow-empty", "-F", "-")
67
69
  end
68
70
  end
69
71
 
@@ -71,14 +73,14 @@ module Tetra
71
73
  def revert_directories(directories, id)
72
74
  Dir.chdir(@directory) do
73
75
  directories.each do |directory|
74
- # reverts added and modified files, both in index and working tree
75
- run("git checkout -f #{id} -- #{directory}")
76
+ git_cmd("checkout", "-f", id, "--", directory)
76
77
 
77
- # compute the list of deleted files
78
- files_in_commit = run("git ls-tree --name-only -r #{id} -- #{directory}").split("\n")
79
- files_in_head = run("git ls-tree --name-only -r HEAD -- #{directory}").split("\n")
80
- files_added_after_head = run("git ls-files -o -- #{directory}").split("\n")
81
- files_to_delete = files_in_head - files_in_commit + files_added_after_head
78
+ # Returns list of files relative to current dir
79
+ files_in_commit = git_cmd("ls-tree", "--name-only", "-r", id, "--", directory).split("\n")
80
+ files_in_head = git_cmd("ls-tree", "--name-only", "-r", "HEAD", "--", directory).split("\n")
81
+ files_added = git_cmd("ls-files", "-o", "--", directory).split("\n")
82
+
83
+ files_to_delete = (files_in_head - files_in_commit) + files_added
82
84
 
83
85
  files_to_delete.each do |file|
84
86
  FileUtils.rm_rf(file)
@@ -91,15 +93,16 @@ module Tetra
91
93
  # leaving changes in the working directory
92
94
  def undo_last_commit
93
95
  Dir.chdir(@directory) do
94
- run("git reset HEAD~")
96
+ git_cmd("reset", "HEAD~")
95
97
  end
96
98
  end
97
99
 
98
100
  # renames git special files to 'disable' them
99
101
  def disable_special_files(path)
100
102
  Dir.chdir(File.join(@directory, path)) do
101
- Find.find(".") do |file|
102
- next unless file =~ /\.git(ignore)?$/
103
+ # We look for .git directories or .gitignore files recursively
104
+ Dir.glob("**/.git*", File::FNM_DOTMATCH).each do |file|
105
+ next unless file.match?(/\.git(ignore)?$/)
103
106
 
104
107
  FileUtils.mv(file, "#{file}_disabled_by_tetra")
105
108
  end
@@ -111,22 +114,28 @@ module Tetra
111
114
  # returns the conflict count
112
115
  def merge_with_id(path, new_path, id)
113
116
  Dir.chdir(@directory) do
114
- run("git show #{id}:#{path} > #{path}.old_version")
117
+ content = git_cmd("show", "#{id}:#{path}")
118
+
119
+ # Write the old version file manually using Ruby
120
+ temp_old_version = "#{path}.old_version"
121
+ File.write(temp_old_version, content)
115
122
 
116
123
  conflict_count = 0
117
124
  begin
118
- run("git merge-file #{path} #{path}.old_version #{new_path} \
119
- -L \"newly generated\" \
120
- -L \"previously generated\" \
121
- -L \"user edited\"")
125
+ git_cmd("merge-file", path, temp_old_version, new_path,
126
+ "-L", "newly generated",
127
+ "-L", "previously generated",
128
+ "-L", "user edited")
122
129
  rescue ExecutionFailed => e
123
130
  if e.status > 0
124
131
  conflict_count = e.status
125
132
  else
126
133
  raise e
127
134
  end
135
+ ensure
136
+ # Clean up the temporary file
137
+ File.delete(temp_old_version) if File.exist?(temp_old_version)
128
138
  end
129
- File.delete("#{path}.old_version")
130
139
  conflict_count
131
140
  end
132
141
  end
@@ -138,12 +147,12 @@ module Tetra
138
147
  Dir.chdir(@directory) do
139
148
  tracked_files = []
140
149
  begin
141
- tracked_files += run("git diff-index --name-only #{id} -- #{directory}").split
150
+ tracked_files += git_cmd("diff-index", "--name-only", id, "--", directory).split
142
151
  rescue ExecutionFailed => e
143
- raise e if e.status != 1 # status 1 is normal
152
+ raise e if e.status != 1
144
153
  end
145
154
 
146
- untracked_files = run("git ls-files --exclude-standard --others -- #{directory}").split
155
+ untracked_files = git_cmd("ls-files", "--exclude-standard", "--others", "--", directory).split
147
156
  tracked_files + untracked_files
148
157
  end
149
158
  end
@@ -152,7 +161,22 @@ module Tetra
152
161
  def archive(directory, id, destination_path)
153
162
  Dir.chdir(@directory) do
154
163
  FileUtils.mkdir_p(File.dirname(destination_path))
155
- run("git archive --format=tar #{id} -- #{directory} | xz -9e > #{destination_path}")
164
+
165
+ log.debug "archiving #{directory} from #{id} to #{destination_path}"
166
+
167
+ # This streams stdout from git directly to stdin of xz without loading
168
+ # data into Ruby memory (which could be big).
169
+ git_command = ["git", "archive", "--format=tar", id, "--", directory]
170
+ xz_command = ["xz", "-9e"]
171
+
172
+ statuses = Open3.pipeline(git_command, xz_command, out: destination_path)
173
+
174
+ unless statuses.all?(&:success?)
175
+ fail ExecutionFailed.new(
176
+ "git archive pipeline failed (exit codes: #{statuses.map(&:exitstatus)})",
177
+ statuses.last.exitstatus
178
+ )
179
+ end
156
180
  end
157
181
  destination_path
158
182
  end
@@ -161,9 +185,20 @@ module Tetra
161
185
  # since from_id
162
186
  def format_patch(directory, from_id, destination_path)
163
187
  Dir.chdir(@directory) do
164
- run("git format-patch -o #{destination_path} --no-numbered #{from_id} -- #{directory}").split
188
+ git_cmd("format-patch", "-o", destination_path, "--no-numbered", from_id, "--", directory).split
165
189
  end
166
190
  end
191
+
192
+ private
193
+
194
+ # Automatically passes "git" as the first argument in an Array.
195
+ def git_cmd(*args)
196
+ run(["git"] + args)
197
+ end
198
+
199
+ def git_cmd_with_stdin(stdin_data, *args)
200
+ run(["git"] + args, false, stdin_data)
201
+ end
167
202
  end
168
203
 
169
204
  class GitAlreadyInitedError < StandardError
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # encapsulates tetra-specific Gradle commandline options
@@ -6,8 +6,9 @@ module Tetra
6
6
  # returns a command line for running Gradle
7
7
  def self.commandline(project_path)
8
8
  gradle_user_home = File.join(project_path, "kit", "gradle-home")
9
+ gradle_bin = File.join(project_path, "gradlew")
9
10
 
10
- "./gradlew --gradle-user-home=#{gradle_user_home}"
11
+ "#{gradle_bin} --gradle-user-home=#{gradle_user_home}"
11
12
  end
12
13
  end
13
14
  end
@@ -1,15 +1,15 @@
1
- # encoding: UTF-8
2
-
1
+ # frozen_string_literal: true
3
2
  module Tetra
4
3
  # encapsulates tetra-specific Maven commandline options
5
4
  class Mvn
6
5
  # returns a command line for running Maven
7
6
  def self.commandline(project_path, mvn_path)
8
- full_path = if mvn_path
9
- File.join(project_path, mvn_path, "mvn")
10
- else
11
- "mvn" # use system-provided executable
12
- end
7
+ executable = if mvn_path
8
+ File.join(project_path, mvn_path, "mvn")
9
+ else
10
+ "mvn" # use system-provided executable
11
+ end
12
+
13
13
  repo_path = File.join(project_path, "kit", "m2")
14
14
  config_path = File.join(project_path, "kit", "m2", "settings.xml")
15
15
 
@@ -19,7 +19,7 @@ module Tetra
19
19
  "--strict-checksums"
20
20
  ]
21
21
 
22
- "#{full_path} #{options.join(' ')}"
22
+ "#{executable} #{options.join(' ')}"
23
23
  end
24
24
  end
25
25
  end
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Tetra
4
4
  # runs programs in subprocesses
@@ -8,62 +8,82 @@ module Tetra
8
8
  # runs a noninteractive executable and returns its output as a string
9
9
  # raises ExecutionFailed if the exit status is not 0
10
10
  # optionally echoes the executable's output/error to standard output/error
11
- def run(commandline, echo = false, stdin = nil)
11
+ def run(commandline, echo = false, stdin_data = nil)
12
12
  log.debug "running `#{commandline}`"
13
13
 
14
- out_recorder = echo ? RecordingIO.new(STDOUT) : RecordingIO.new
15
- err_recorder = echo ? RecordingIO.new(STDERR) : RecordingIO.new
14
+ # Prepare buffers to capture output
15
+ out_buffer = StringIO.new
16
+ err_buffer = StringIO.new
17
+ exit_status = nil
18
+ # Flatten handles nested arrays, Compact removes nils
19
+ cmd_args = Array(commandline).flatten.compact.map(&:to_s)
16
20
 
17
- status = Open4.spawn(commandline, stdin: stdin, stdout: out_recorder,
18
- stderr: err_recorder, quiet: true).exitstatus
21
+ Open3.popen3(*cmd_args) do |stdin, stdout, stderr, wait_thr|
22
+ # 1. Handle Input (if any)
23
+ stdin.write(stdin_data) if stdin_data
24
+ stdin.close # Close stdin so the process knows input is finished
19
25
 
20
- log.debug "`#{commandline}` exited with status #{status}"
26
+ # Use threads to read stdout and stderr simultaneously.
27
+ readers = []
21
28
 
22
- if status != 0
23
- log.warn("`#{commandline}` failed with status #{status}")
24
- out = out_recorder.record
25
- err = err_recorder.record
26
- if out != "" || err != ""
29
+ readers << Thread.new do
30
+ stdout.each_line do |line|
31
+ print line if echo # Echo to real STDOUT if requested
32
+ out_buffer << line # Capture to memory
33
+ end
34
+ end
35
+
36
+ readers << Thread.new do
37
+ stderr.each_line do |line|
38
+ $stderr.print line if echo # Echo to real STDERR if requested
39
+ err_buffer << line # Capture to memory
40
+ end
41
+ end
42
+
43
+ # Wait for reading to finish
44
+ readers.each(&:join)
45
+
46
+ # Get the exit code
47
+ exit_status = wait_thr.value
48
+ end
49
+
50
+ # Check for failure
51
+ unless exit_status.success?
52
+ # Extract strings from buffers
53
+ out = out_buffer.string
54
+ err = err_buffer.string
55
+
56
+ log.warn("`#{commandline}` failed with status #{exit_status.exitstatus}")
57
+
58
+ if !out.empty? || !err.empty?
27
59
  log.warn("Output follows:")
28
- log.warn(out) unless out == ""
29
- log.warn(err) unless err == ""
60
+ log.warn(out) unless out.empty?
61
+ log.warn(err) unless err.empty?
30
62
  end
31
- fail ExecutionFailed.new(commandline, status, out, err)
63
+
64
+ fail ExecutionFailed.new(commandline, exit_status.exitstatus, out, err)
32
65
  end
33
66
 
34
- out_recorder.record
67
+ # Return the standard output
68
+ out_buffer.string
35
69
  end
36
70
 
37
71
  # runs an interactive executable in a subshell
38
72
  def run_interactive(command)
39
- log.debug "running `#{command}`"
40
- success = system({}, command)
41
- log.debug "`#{command}` exited with success #{success}"
42
- fail ExecutionFailed.new(command, $CHILD_STATUS, nil, nil) unless success
43
- end
73
+ log.debug "running interactive `#{command}`"
44
74
 
45
- # records bytes sent via "<<" for later use
46
- # optionally echoes to another IO object
47
- class RecordingIO
48
- attr_reader :record
75
+ # system() passes control to the subprocess
76
+ cmd_args = Array(command).flatten.compact.map(&:to_s)
77
+ success = system(*cmd_args)
49
78
 
50
- def initialize(io = nil)
51
- @io = io
52
- @record = ""
53
- end
79
+ log.debug "`#{command}` exited with success #{success}"
54
80
 
55
- def <<(*args)
56
- if @io
57
- @io.<<(*args)
58
- @io.flush
59
- end
60
- @record.<<(*args)
61
- end
81
+ fail ExecutionFailed.new(command, $CHILD_STATUS.exitstatus, nil, nil) unless success
62
82
  end
63
83
  end
64
84
 
65
85
  # raised when a command returns a non-zero status
66
- class ExecutionFailed < Exception
86
+ class ExecutionFailed < StandardError
67
87
  attr_reader :commandline
68
88
  attr_reader :status
69
89
  attr_reader :out
@@ -74,6 +94,7 @@ module Tetra
74
94
  @status = status
75
95
  @out = out
76
96
  @err = err
97
+ super("Command failed: #{commandline} (status: #{status})")
77
98
  end
78
99
 
79
100
  def to_s
@@ -1,5 +1,4 @@
1
- # encoding: UTF-8
2
-
1
+ # frozen_string_literal: true
3
2
  module Tetra
4
3
  # encapsulates tar
5
4
  class Tar
@@ -7,8 +6,10 @@ module Tetra
7
6
 
8
7
  # decompresses a file in a target directory
9
8
  def decompress(tarfile, directory)
10
- result = run("tar xvf #{tarfile} --directory #{directory}")
11
- result.strip if result != ""
9
+ # Use Array format to prevent shell injection.
10
+ result = run(["tar", "xvf", tarfile, "--directory", directory])
11
+
12
+ result&.strip
12
13
  end
13
14
  end
14
15
  end
@@ -1,5 +1,4 @@
1
- # encoding: UTF-8
2
-
1
+ # frozen_string_literal: true
3
2
  module Tetra
4
3
  # encapsulates unzip
5
4
  class Unzip
@@ -7,8 +6,10 @@ module Tetra
7
6
 
8
7
  # decompresses a file in a target directory
9
8
  def decompress(zipfile, directory)
10
- result = run("unzip #{zipfile} -d #{directory}")
11
- result.strip if result != ""
9
+ # Use Array execution to prevent shell injection
10
+ result = run(["unzip", zipfile, "-d", directory])
11
+
12
+ result&.strip
12
13
  end
13
14
  end
14
15
  end