mnenv 0.1.0 → 0.1.2

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 (306) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/PROPOSAL.md +197 -0
  4. data/README.adoc +168 -461
  5. data/Rakefile +7 -4
  6. data/bin/Install-Mnenv.ps1 +145 -0
  7. data/bin/mnenv-installer +72 -0
  8. data/completions/bash +47 -0
  9. data/completions/fish +29 -0
  10. data/completions/powershell.ps1 +94 -0
  11. data/completions/zsh +43 -0
  12. data/lib/mnenv/binary_repository.rb +189 -0
  13. data/lib/mnenv/chocolatey.rb +7 -0
  14. data/lib/mnenv/cli.rb +110 -10
  15. data/lib/mnenv/commands/available_command.rb +169 -0
  16. data/lib/mnenv/commands/chocolatey_command.rb +4 -5
  17. data/lib/mnenv/commands/gemfile_command.rb +4 -5
  18. data/lib/mnenv/commands/homebrew_command.rb +4 -5
  19. data/lib/mnenv/commands/install_command.rb +234 -0
  20. data/lib/mnenv/commands/snap_command.rb +5 -7
  21. data/lib/mnenv/commands/uninstall_command.rb +111 -0
  22. data/lib/mnenv/commands/version_command.rb +167 -0
  23. data/lib/mnenv/commands.rb +9 -4
  24. data/lib/mnenv/gemfile/extractor.rb +10 -3
  25. data/lib/mnenv/gemfile.rb +8 -0
  26. data/lib/mnenv/gemfile_repository.rb +0 -2
  27. data/lib/mnenv/homebrew.rb +7 -0
  28. data/lib/mnenv/installer/base.rb +62 -0
  29. data/lib/mnenv/installer/factory.rb +46 -0
  30. data/lib/mnenv/installer.rb +12 -0
  31. data/lib/mnenv/installers/binary_installer.rb +242 -0
  32. data/lib/mnenv/installers/gemfile_installer.rb +76 -0
  33. data/lib/mnenv/json_formatter.rb +3 -13
  34. data/lib/mnenv/logger.rb +9 -1
  35. data/lib/mnenv/models/binary_version.rb +78 -0
  36. data/lib/mnenv/models/chocolatey_version.rb +7 -0
  37. data/lib/mnenv/models/gemfile_version.rb +19 -5
  38. data/lib/mnenv/models/homebrew_version.rb +7 -0
  39. data/lib/mnenv/models/snap_version.rb +8 -0
  40. data/lib/mnenv/models/version.rb +16 -0
  41. data/lib/mnenv/models.rb +7 -5
  42. data/lib/mnenv/paths.rb +69 -0
  43. data/lib/mnenv/platform_detector.rb +109 -0
  44. data/lib/mnenv/repository.rb +50 -35
  45. data/lib/mnenv/resolver +72 -0
  46. data/lib/mnenv/shells/base.rb +32 -0
  47. data/lib/mnenv/shells/bash.rb +72 -0
  48. data/lib/mnenv/shells/cmd.rb +108 -0
  49. data/lib/mnenv/shells/factory.rb +82 -0
  50. data/lib/mnenv/shells/power_shell.rb +110 -0
  51. data/lib/mnenv/shim_manager.rb +121 -0
  52. data/lib/mnenv/snap.rb +7 -0
  53. data/lib/mnenv/snap_repository.rb +2 -19
  54. data/lib/mnenv/source_registry.rb +69 -0
  55. data/lib/mnenv/sources.rb +46 -0
  56. data/lib/mnenv/version.rb +1 -1
  57. data/lib/mnenv/version_resolver.rb +108 -0
  58. data/lib/mnenv/versions_manager.rb +92 -0
  59. data/lib/mnenv.rb +6 -0
  60. data/mnenv.gemspec +4 -1
  61. data/scripts/cross-source-switching-test.sh +214 -0
  62. data/scripts/integration-test.sh +89 -0
  63. data/scripts/version-switching-test.sh +151 -0
  64. metadata +85 -247
  65. data/data/chocolatey/versions.yaml +0 -812
  66. data/data/gemfile/v1.1.6/Gemfile +0 -4
  67. data/data/gemfile/v1.1.6/Gemfile.lock.archived +0 -232
  68. data/data/gemfile/v1.1.7/Gemfile +0 -4
  69. data/data/gemfile/v1.1.7/Gemfile.lock.archived +0 -235
  70. data/data/gemfile/v1.1.8/Gemfile +0 -4
  71. data/data/gemfile/v1.1.8/Gemfile.lock.archived +0 -238
  72. data/data/gemfile/v1.10.0/Gemfile +0 -5
  73. data/data/gemfile/v1.10.0/Gemfile.lock.archived +0 -930
  74. data/data/gemfile/v1.10.1/Gemfile +0 -5
  75. data/data/gemfile/v1.10.1/Gemfile.lock.archived +0 -929
  76. data/data/gemfile/v1.10.10/Gemfile +0 -5
  77. data/data/gemfile/v1.10.10/Gemfile.lock.archived +0 -973
  78. data/data/gemfile/v1.10.11/Gemfile +0 -5
  79. data/data/gemfile/v1.10.11/Gemfile.lock.archived +0 -975
  80. data/data/gemfile/v1.10.2/Gemfile +0 -5
  81. data/data/gemfile/v1.10.2/Gemfile.lock.archived +0 -939
  82. data/data/gemfile/v1.10.3/Gemfile +0 -5
  83. data/data/gemfile/v1.10.3/Gemfile.lock.archived +0 -946
  84. data/data/gemfile/v1.10.5/Gemfile +0 -5
  85. data/data/gemfile/v1.10.5/Gemfile.lock.archived +0 -958
  86. data/data/gemfile/v1.10.6/Gemfile +0 -5
  87. data/data/gemfile/v1.10.6/Gemfile.lock.archived +0 -969
  88. data/data/gemfile/v1.10.7/Gemfile +0 -5
  89. data/data/gemfile/v1.10.7/Gemfile.lock.archived +0 -969
  90. data/data/gemfile/v1.10.8/Gemfile +0 -5
  91. data/data/gemfile/v1.10.8/Gemfile.lock.archived +0 -968
  92. data/data/gemfile/v1.10.9/Gemfile +0 -5
  93. data/data/gemfile/v1.10.9/Gemfile.lock.archived +0 -972
  94. data/data/gemfile/v1.11.0/Gemfile +0 -5
  95. data/data/gemfile/v1.11.0/Gemfile.lock.archived +0 -971
  96. data/data/gemfile/v1.11.1/Gemfile +0 -5
  97. data/data/gemfile/v1.11.1/Gemfile.lock.archived +0 -975
  98. data/data/gemfile/v1.11.4/Gemfile +0 -5
  99. data/data/gemfile/v1.11.4/Gemfile.lock.archived +0 -1046
  100. data/data/gemfile/v1.11.5/Gemfile +0 -5
  101. data/data/gemfile/v1.11.5/Gemfile.lock.archived +0 -1047
  102. data/data/gemfile/v1.12.10/Gemfile +0 -3
  103. data/data/gemfile/v1.12.10/Gemfile.lock.archived +0 -1073
  104. data/data/gemfile/v1.12.3/Gemfile +0 -3
  105. data/data/gemfile/v1.12.3/Gemfile.lock.archived +0 -1050
  106. data/data/gemfile/v1.12.4/Gemfile +0 -3
  107. data/data/gemfile/v1.12.4/Gemfile.lock.archived +0 -1056
  108. data/data/gemfile/v1.12.5/Gemfile +0 -3
  109. data/data/gemfile/v1.12.5/Gemfile.lock.archived +0 -1054
  110. data/data/gemfile/v1.12.6/Gemfile +0 -3
  111. data/data/gemfile/v1.12.6/Gemfile.lock.archived +0 -1056
  112. data/data/gemfile/v1.12.8/Gemfile +0 -3
  113. data/data/gemfile/v1.12.8/Gemfile.lock.archived +0 -1063
  114. data/data/gemfile/v1.13.0/Gemfile +0 -3
  115. data/data/gemfile/v1.13.0/Gemfile.lock.archived +0 -1074
  116. data/data/gemfile/v1.13.2/Gemfile +0 -3
  117. data/data/gemfile/v1.13.2/Gemfile.lock.archived +0 -899
  118. data/data/gemfile/v1.13.3/Gemfile +0 -3
  119. data/data/gemfile/v1.13.3/Gemfile.lock.archived +0 -938
  120. data/data/gemfile/v1.13.4/Gemfile +0 -3
  121. data/data/gemfile/v1.13.4/Gemfile.lock.archived +0 -938
  122. data/data/gemfile/v1.13.5/Gemfile +0 -3
  123. data/data/gemfile/v1.13.5/Gemfile.lock.archived +0 -944
  124. data/data/gemfile/v1.13.7/Gemfile +0 -3
  125. data/data/gemfile/v1.13.7/Gemfile.lock.archived +0 -944
  126. data/data/gemfile/v1.13.8/Gemfile +0 -3
  127. data/data/gemfile/v1.13.8/Gemfile.lock.archived +0 -944
  128. data/data/gemfile/v1.13.9/Gemfile +0 -3
  129. data/data/gemfile/v1.13.9/Gemfile.lock.archived +0 -956
  130. data/data/gemfile/v1.14.3/Gemfile +0 -3
  131. data/data/gemfile/v1.14.3/Gemfile.lock.archived +0 -950
  132. data/data/gemfile/v1.2.12/Gemfile +0 -3
  133. data/data/gemfile/v1.2.12/Gemfile.lock.archived +0 -283
  134. data/data/gemfile/v1.2.2/Gemfile +0 -4
  135. data/data/gemfile/v1.2.2/Gemfile.lock.archived +0 -224
  136. data/data/gemfile/v1.2.3/Gemfile +0 -4
  137. data/data/gemfile/v1.2.3/Gemfile.lock.archived +0 -231
  138. data/data/gemfile/v1.2.6/Gemfile +0 -4
  139. data/data/gemfile/v1.2.6/Gemfile.lock.archived +0 -239
  140. data/data/gemfile/v1.2.8/Gemfile +0 -4
  141. data/data/gemfile/v1.2.8/Gemfile.lock.archived +0 -233
  142. data/data/gemfile/v1.2.9/Gemfile +0 -4
  143. data/data/gemfile/v1.2.9/Gemfile.lock.archived +0 -245
  144. data/data/gemfile/v1.3.1/Gemfile +0 -3
  145. data/data/gemfile/v1.3.1/Gemfile.lock.archived +0 -296
  146. data/data/gemfile/v1.3.2/Gemfile +0 -3
  147. data/data/gemfile/v1.3.2/Gemfile.lock.archived +0 -296
  148. data/data/gemfile/v1.3.4/Gemfile +0 -3
  149. data/data/gemfile/v1.3.4/Gemfile.lock.archived +0 -284
  150. data/data/gemfile/v1.3.5/Gemfile +0 -3
  151. data/data/gemfile/v1.3.5/Gemfile.lock.archived +0 -284
  152. data/data/gemfile/v1.3.6/Gemfile +0 -3
  153. data/data/gemfile/v1.3.6/Gemfile.lock.archived +0 -286
  154. data/data/gemfile/v1.3.9/Gemfile +0 -3
  155. data/data/gemfile/v1.3.9/Gemfile.lock.archived +0 -334
  156. data/data/gemfile/v1.4.0/Gemfile +0 -3
  157. data/data/gemfile/v1.4.0/Gemfile.lock.archived +0 -330
  158. data/data/gemfile/v1.4.10/Gemfile +0 -4
  159. data/data/gemfile/v1.4.10/Gemfile.lock.archived +0 -461
  160. data/data/gemfile/v1.4.11/Gemfile +0 -4
  161. data/data/gemfile/v1.4.11/Gemfile.lock.archived +0 -452
  162. data/data/gemfile/v1.4.12/Gemfile +0 -4
  163. data/data/gemfile/v1.4.12/Gemfile.lock.archived +0 -452
  164. data/data/gemfile/v1.4.13/Gemfile +0 -4
  165. data/data/gemfile/v1.4.13/Gemfile.lock.archived +0 -455
  166. data/data/gemfile/v1.4.14/Gemfile +0 -4
  167. data/data/gemfile/v1.4.14/Gemfile.lock.archived +0 -456
  168. data/data/gemfile/v1.4.18/Gemfile +0 -3
  169. data/data/gemfile/v1.4.18/Gemfile.lock.archived +0 -486
  170. data/data/gemfile/v1.4.3/Gemfile +0 -3
  171. data/data/gemfile/v1.4.3/Gemfile.lock.archived +0 -339
  172. data/data/gemfile/v1.4.4/Gemfile +0 -3
  173. data/data/gemfile/v1.4.4/Gemfile.lock.archived +0 -339
  174. data/data/gemfile/v1.4.5/Gemfile +0 -3
  175. data/data/gemfile/v1.4.5/Gemfile.lock.archived +0 -348
  176. data/data/gemfile/v1.4.6/Gemfile +0 -3
  177. data/data/gemfile/v1.4.6/Gemfile.lock.archived +0 -357
  178. data/data/gemfile/v1.4.7/Gemfile +0 -3
  179. data/data/gemfile/v1.4.7/Gemfile.lock.archived +0 -391
  180. data/data/gemfile/v1.4.8/Gemfile +0 -3
  181. data/data/gemfile/v1.4.8/Gemfile.lock.archived +0 -445
  182. data/data/gemfile/v1.4.9/Gemfile +0 -3
  183. data/data/gemfile/v1.4.9/Gemfile.lock.archived +0 -448
  184. data/data/gemfile/v1.5.0/Gemfile +0 -3
  185. data/data/gemfile/v1.5.0/Gemfile.lock.archived +0 -478
  186. data/data/gemfile/v1.5.10/Gemfile +0 -3
  187. data/data/gemfile/v1.5.10/Gemfile.lock.archived +0 -668
  188. data/data/gemfile/v1.5.11/Gemfile +0 -3
  189. data/data/gemfile/v1.5.11/Gemfile.lock.archived +0 -668
  190. data/data/gemfile/v1.5.15/Gemfile +0 -3
  191. data/data/gemfile/v1.5.15/Gemfile.lock.archived +0 -686
  192. data/data/gemfile/v1.5.16/Gemfile +0 -3
  193. data/data/gemfile/v1.5.16/Gemfile.lock.archived +0 -684
  194. data/data/gemfile/v1.5.17/Gemfile +0 -3
  195. data/data/gemfile/v1.5.17/Gemfile.lock.archived +0 -684
  196. data/data/gemfile/v1.5.18/Gemfile +0 -5
  197. data/data/gemfile/v1.5.18/Gemfile.lock.archived +0 -691
  198. data/data/gemfile/v1.5.19/Gemfile +0 -5
  199. data/data/gemfile/v1.5.19/Gemfile.lock.archived +0 -703
  200. data/data/gemfile/v1.5.20/Gemfile +0 -5
  201. data/data/gemfile/v1.5.20/Gemfile.lock.archived +0 -703
  202. data/data/gemfile/v1.5.21/Gemfile +0 -5
  203. data/data/gemfile/v1.5.21/Gemfile.lock.archived +0 -707
  204. data/data/gemfile/v1.5.22/Gemfile +0 -5
  205. data/data/gemfile/v1.5.22/Gemfile.lock.archived +0 -707
  206. data/data/gemfile/v1.5.23/Gemfile +0 -5
  207. data/data/gemfile/v1.5.23/Gemfile.lock.archived +0 -711
  208. data/data/gemfile/v1.5.24/Gemfile +0 -5
  209. data/data/gemfile/v1.5.24/Gemfile.lock.archived +0 -711
  210. data/data/gemfile/v1.5.3/Gemfile +0 -3
  211. data/data/gemfile/v1.5.3/Gemfile.lock.archived +0 -651
  212. data/data/gemfile/v1.5.4/Gemfile +0 -3
  213. data/data/gemfile/v1.5.4/Gemfile.lock.archived +0 -657
  214. data/data/gemfile/v1.5.5/Gemfile +0 -3
  215. data/data/gemfile/v1.5.5/Gemfile.lock.archived +0 -657
  216. data/data/gemfile/v1.5.6/Gemfile +0 -3
  217. data/data/gemfile/v1.5.6/Gemfile.lock.archived +0 -657
  218. data/data/gemfile/v1.5.7/Gemfile +0 -3
  219. data/data/gemfile/v1.5.7/Gemfile.lock.archived +0 -657
  220. data/data/gemfile/v1.5.8/Gemfile +0 -3
  221. data/data/gemfile/v1.5.8/Gemfile.lock.archived +0 -655
  222. data/data/gemfile/v1.5.9/Gemfile +0 -3
  223. data/data/gemfile/v1.5.9/Gemfile.lock.archived +0 -656
  224. data/data/gemfile/v1.6.1/Gemfile +0 -5
  225. data/data/gemfile/v1.6.1/Gemfile.lock.archived +0 -721
  226. data/data/gemfile/v1.6.10/Gemfile +0 -5
  227. data/data/gemfile/v1.6.10/Gemfile.lock.archived +0 -744
  228. data/data/gemfile/v1.6.11/Gemfile +0 -5
  229. data/data/gemfile/v1.6.11/Gemfile.lock.archived +0 -744
  230. data/data/gemfile/v1.6.12/Gemfile +0 -5
  231. data/data/gemfile/v1.6.12/Gemfile.lock.archived +0 -745
  232. data/data/gemfile/v1.6.13/Gemfile +0 -5
  233. data/data/gemfile/v1.6.13/Gemfile.lock.archived +0 -745
  234. data/data/gemfile/v1.6.14/Gemfile +0 -5
  235. data/data/gemfile/v1.6.14/Gemfile.lock.archived +0 -754
  236. data/data/gemfile/v1.6.15/Gemfile +0 -5
  237. data/data/gemfile/v1.6.15/Gemfile.lock.archived +0 -757
  238. data/data/gemfile/v1.6.2/Gemfile +0 -5
  239. data/data/gemfile/v1.6.2/Gemfile.lock.archived +0 -718
  240. data/data/gemfile/v1.6.3/Gemfile +0 -5
  241. data/data/gemfile/v1.6.3/Gemfile.lock.archived +0 -728
  242. data/data/gemfile/v1.6.4/Gemfile +0 -5
  243. data/data/gemfile/v1.6.4/Gemfile.lock.archived +0 -730
  244. data/data/gemfile/v1.6.5/Gemfile +0 -5
  245. data/data/gemfile/v1.6.5/Gemfile.lock.archived +0 -733
  246. data/data/gemfile/v1.6.6/Gemfile +0 -5
  247. data/data/gemfile/v1.6.6/Gemfile.lock.archived +0 -733
  248. data/data/gemfile/v1.6.7/Gemfile +0 -5
  249. data/data/gemfile/v1.6.7/Gemfile.lock.archived +0 -733
  250. data/data/gemfile/v1.6.9/Gemfile +0 -5
  251. data/data/gemfile/v1.6.9/Gemfile.lock.archived +0 -744
  252. data/data/gemfile/v1.7.0/Gemfile +0 -5
  253. data/data/gemfile/v1.7.0/Gemfile.lock.archived +0 -750
  254. data/data/gemfile/v1.7.1/Gemfile +0 -5
  255. data/data/gemfile/v1.7.1/Gemfile.lock.archived +0 -750
  256. data/data/gemfile/v1.7.2/Gemfile +0 -5
  257. data/data/gemfile/v1.7.2/Gemfile.lock.archived +0 -747
  258. data/data/gemfile/v1.7.3/Gemfile +0 -5
  259. data/data/gemfile/v1.7.3/Gemfile.lock.archived +0 -755
  260. data/data/gemfile/v1.7.4/Gemfile +0 -5
  261. data/data/gemfile/v1.7.4/Gemfile.lock.archived +0 -756
  262. data/data/gemfile/v1.7.5/Gemfile +0 -5
  263. data/data/gemfile/v1.7.5/Gemfile.lock.archived +0 -759
  264. data/data/gemfile/v1.7.6/Gemfile +0 -5
  265. data/data/gemfile/v1.7.6/Gemfile.lock.archived +0 -768
  266. data/data/gemfile/v1.8.10/Gemfile +0 -5
  267. data/data/gemfile/v1.8.10/Gemfile.lock.archived +0 -792
  268. data/data/gemfile/v1.8.11/Gemfile +0 -5
  269. data/data/gemfile/v1.8.11/Gemfile.lock.archived +0 -862
  270. data/data/gemfile/v1.8.3/Gemfile +0 -5
  271. data/data/gemfile/v1.8.3/Gemfile.lock.archived +0 -773
  272. data/data/gemfile/v1.8.4/Gemfile +0 -5
  273. data/data/gemfile/v1.8.4/Gemfile.lock.archived +0 -768
  274. data/data/gemfile/v1.8.5/Gemfile +0 -5
  275. data/data/gemfile/v1.8.5/Gemfile.lock.archived +0 -768
  276. data/data/gemfile/v1.8.6/Gemfile +0 -5
  277. data/data/gemfile/v1.8.6/Gemfile.lock.archived +0 -777
  278. data/data/gemfile/v1.8.7/Gemfile +0 -5
  279. data/data/gemfile/v1.8.7/Gemfile.lock.archived +0 -777
  280. data/data/gemfile/v1.8.8/Gemfile +0 -5
  281. data/data/gemfile/v1.8.8/Gemfile.lock.archived +0 -778
  282. data/data/gemfile/v1.8.9/Gemfile +0 -5
  283. data/data/gemfile/v1.8.9/Gemfile.lock.archived +0 -775
  284. data/data/gemfile/v1.9.0/Gemfile +0 -5
  285. data/data/gemfile/v1.9.0/Gemfile.lock.archived +0 -871
  286. data/data/gemfile/v1.9.1/Gemfile +0 -5
  287. data/data/gemfile/v1.9.1/Gemfile.lock.archived +0 -906
  288. data/data/gemfile/v1.9.2/Gemfile +0 -5
  289. data/data/gemfile/v1.9.2/Gemfile.lock.archived +0 -898
  290. data/data/gemfile/v1.9.3/Gemfile +0 -5
  291. data/data/gemfile/v1.9.3/Gemfile.lock.archived +0 -898
  292. data/data/gemfile/v1.9.4/Gemfile +0 -5
  293. data/data/gemfile/v1.9.4/Gemfile.lock.archived +0 -901
  294. data/data/gemfile/v1.9.5/Gemfile +0 -5
  295. data/data/gemfile/v1.9.5/Gemfile.lock.archived +0 -903
  296. data/data/gemfile/v1.9.6/Gemfile +0 -5
  297. data/data/gemfile/v1.9.6/Gemfile.lock.archived +0 -900
  298. data/data/gemfile/v1.9.7/Gemfile +0 -5
  299. data/data/gemfile/v1.9.7/Gemfile.lock.archived +0 -922
  300. data/data/gemfile/v1.9.8/Gemfile +0 -5
  301. data/data/gemfile/v1.9.8/Gemfile.lock.archived +0 -933
  302. data/data/gemfile/versions.yaml +0 -751
  303. data/data/homebrew/versions.yaml +0 -567
  304. data/data/snap/github_tags.json +0 -42
  305. data/data/snap/versions.yaml +0 -589
  306. data/snapcraft-list-copied-from-site.md +0 -101
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rspec/core/rake_task'
4
3
  require 'bundler/gem_tasks'
5
4
 
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ task default: :spec
9
+ rescue LoadError
10
+ # rspec not available, skip spec task
11
+ end
@@ -0,0 +1,145 @@
1
+ # One-line installer for mnenv (Windows)
2
+ # Install: Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/metanorma/mnenv/main/bin/Install-Mnenv.ps1'))
3
+
4
+ # Copyright 2024 Metanorma mnenv project
5
+ # Licensed under Apache License 2.0
6
+
7
+ [CmdletBinding()]
8
+ param(
9
+ [Parameter(Mandatory = $false)]
10
+ [string]$MnenvRoot = $env:MNENV_ROOT,
11
+
12
+ [Parameter(Mandatory = $false)]
13
+ [string]$RepoUrl = "https://github.com/metanorma/mnenv"
14
+ )
15
+
16
+ $ErrorActionPreference = "Stop"
17
+
18
+ # Set TLS 1.2 (required for GitHub)
19
+ try {
20
+ Write-Host "Forcing web requests to allow TLS v1.2 (Required for GitHub)"
21
+ [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
22
+ }
23
+ catch {
24
+ Write-Warning "Unable to set TLS 1.2. Installation may fail on older systems."
25
+ }
26
+
27
+ function Get-Downloader {
28
+ param(
29
+ [string]$Url,
30
+ [string]$ProxyUrl
31
+ )
32
+
33
+ $downloader = New-Object System.Net.WebClient
34
+ $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials
35
+ if ($defaultCreds) {
36
+ $downloader.Credentials = $defaultCreds
37
+ }
38
+
39
+ if ($ProxyUrl) {
40
+ Write-Host "Using proxy server: $ProxyUrl"
41
+ $proxy = New-Object System.Net.WebProxy -ArgumentList $ProxyUrl, $true
42
+ $proxy.Credentials = $defaultCreds
43
+ if (-not $proxy.IsBypassed($Url)) {
44
+ $downloader.Proxy = $proxy
45
+ }
46
+ }
47
+
48
+ $downloader
49
+ }
50
+
51
+ function Test-MnenvInstalled {
52
+ $checkPath = if ($MnenvRoot) { $MnenvRoot } else { Join-Path $env:USERPROFILE ".mnenv" }
53
+
54
+ if (Test-Path $checkPath) {
55
+ $files = Get-ChildItem $checkPath -ErrorAction SilentlyContinue
56
+ if ($files) {
57
+ Write-Warning "Files from a previous mnenv installation were found at '$checkPath'."
58
+ Write-Host "To reinstall, remove the directory and run this script again."
59
+ return $true
60
+ }
61
+ }
62
+ $false
63
+ }
64
+
65
+ function Main {
66
+ $actualMnenvRoot = if ($MnenvRoot) { $MnenvRoot } else { Join-Path $env:USERPROFILE ".mnenv" }
67
+
68
+ Write-Host "==> Installing mnenv to $actualMnenvRoot"
69
+
70
+ # Check for existing installation
71
+ if (Test-MnenvInstalled) {
72
+ Write-Host "Existing installation detected. Aborting."
73
+ Write-Host "To reinstall, first remove: $actualMnenvRoot"
74
+ return
75
+ }
76
+
77
+ # Clone or update repository
78
+ if (Test-Path $actualMnenvRoot) {
79
+ Write-Host "==> Updating existing installation"
80
+ Set-Location $actualMnenvRoot
81
+ & git pull
82
+ }
83
+ else {
84
+ Write-Host "==> Cloning repository from $RepoUrl"
85
+ & git clone $RepoUrl $actualMnenvRoot
86
+ }
87
+
88
+ # Create directory structure
89
+ $versionsDir = Join-Path $actualMnenvRoot "versions"
90
+ $shimsDir = Join-Path $actualMnenvRoot "shims"
91
+ $cacheDir = Join-Path $actualMnenvRoot "cache"
92
+ $completionsDir = Join-Path $actualMnenvRoot "completions"
93
+
94
+ @($versionsDir, $shimsDir, $cacheDir, $completionsDir) | ForEach-Object {
95
+ if (-not (Test-Path $_)) {
96
+ New-Item -ItemType Directory -Path $_ -Force | Out-Null
97
+ }
98
+ }
99
+
100
+ # Setup PowerShell profile
101
+ Setup-PowerShell $actualMnenvRoot
102
+
103
+ Write-Host "==> Installation complete!"
104
+ Write-Host "==> Reload your shell: . `$PROFILE"
105
+ Write-Host "==> Then run: mnenv install --list"
106
+ }
107
+
108
+ function Setup-PowerShell {
109
+ param([string]$RootPath)
110
+
111
+ $profilePath = $PROFILE.CurrentUserCurrentHost
112
+ $shimsPath = Join-Path $RootPath "shims"
113
+ $completionsPath = Join-Path $RootPath "completions\powershell.ps1"
114
+ $initLine = "`$env:PATH = `"$shimsPath;`$env:PATH`""
115
+ $completionLine = ". `"$completionsPath`""
116
+
117
+ # Ensure profile exists
118
+ if (-not (Test-Path $profilePath)) {
119
+ New-Item -ItemType File -Path $profilePath -Force | Out-Null
120
+ }
121
+
122
+ $profileContent = Get-Content $profilePath -Raw
123
+
124
+ # Add shims to PATH if not already present
125
+ if ($profileContent -notlike "*$shimsPath*") {
126
+ Add-Content $profilePath "`n# Mnenv"
127
+ Add-Content $profilePath $initLine
128
+ Write-Host "==> Added mnenv shims to PATH in $profilePath"
129
+ }
130
+
131
+ # Add completion if not already present
132
+ if ($profileContent -notlike "*$completionsPath*") {
133
+ Add-Content $profilePath $completionLine
134
+ Write-Host "==> Added mnenv completion to $profilePath"
135
+ }
136
+ }
137
+
138
+ try {
139
+ Main
140
+ }
141
+ catch {
142
+ Write-Error "Installation failed: $_"
143
+ Write-Host "For help, visit: https://github.com/metanorma/mnenv"
144
+ exit 1
145
+ }
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # One-line installer for mnenv (Unix/macOS)
3
+ # Install: curl -fsSL https://raw.githubusercontent.com/metanorma/mnenv/main/bin/mnenv-installer | bash
4
+
5
+ set -e
6
+
7
+ MNENV_ROOT="${MNENV_ROOT:-$HOME/.mnenv}"
8
+ REPO_URL="https://github.com/metanorma/mnenv"
9
+
10
+ main() {
11
+ echo "==> Installing mnenv to $MNENV_ROOT"
12
+
13
+ # Clone or update repository
14
+ if [ -d "$MNENV_ROOT" ]; then
15
+ echo "==> Updating existing installation"
16
+ cd "$MNENV_ROOT"
17
+ git pull
18
+ else
19
+ echo "==> Cloning repository"
20
+ git clone "$REPO_URL" "$MNENV_ROOT"
21
+ fi
22
+
23
+ # Setup shell integration
24
+ setup_shell
25
+
26
+ # Create directory structure
27
+ mkdir -p "$MNENV_ROOT/versions"
28
+ mkdir -p "$MNENV_ROOT/shims"
29
+ mkdir -p "$MNENV_ROOT/cache"
30
+
31
+ echo "==> Installation complete!"
32
+ echo "==> Reload your shell or run: source ~/.mnenv-init"
33
+ echo "==> Then run: mnenv install --list"
34
+ }
35
+
36
+ setup_shell() {
37
+ local shell_name="$(basename "$SHELL")"
38
+
39
+ case "$shell_name" in
40
+ bash)
41
+ add_to_shell_config ~/.bashrc "source \"$MNENV_ROOT/completions/bash\""
42
+ ;;
43
+ zsh)
44
+ add_to_shell_config ~/.zshrc "source \"$MNENV_ROOT/completions/zsh\""
45
+ ;;
46
+ fish)
47
+ add_to_shell_config ~/.config/fish/config.fish "source \"$MNENV_ROOT/completions/fish\""
48
+ ;;
49
+ *)
50
+ echo "==> Unsupported shell: $shell_name"
51
+ echo "==> Manually add: source $MNENV_ROOT/completions/$shell_name"
52
+ ;;
53
+ esac
54
+ }
55
+
56
+ add_to_shell_config() {
57
+ local config_file="$1"
58
+ local init_line="$2"
59
+
60
+ if [ -f "$config_file" ] && ! grep -q "$MNENV_ROOT" "$config_file" 2>/dev/null; then
61
+ echo "" >> "$config_file"
62
+ echo "# Mnenv" >> "$config_file"
63
+ echo "$init_line" >> "$config_file"
64
+ echo "==> Added mnenv to $config_file"
65
+ elif [ ! -f "$config_file" ]; then
66
+ echo "# Mnenv" >> "$config_file"
67
+ echo "$init_line" >> "$config_file"
68
+ echo "==> Created $config_file and added mnenv"
69
+ fi
70
+ }
71
+
72
+ main "$@"
data/completions/bash ADDED
@@ -0,0 +1,47 @@
1
+ # Mnenv Bash completion
2
+
3
+ _mnenv_install() {
4
+ local cur="${COMP_WORDS[COMP_CWORD]}"
5
+ local versions=$(/Users/mulgogi/.gem/ruby/3.3.0/bin/mnenv gemfile list 2>/dev/null | grep -E '^v[0-9]' | awk '{print $1}')
6
+ COMPREPLY=($(compgen -W "$versions --list --interactive" -- "$cur"))
7
+ }
8
+
9
+ _mnenv_use() {
10
+ local cur="${COMP_WORDS[COMP_CWORD]}"
11
+ local versions=$(ls -1 ~/.mnenv/versions/ 2>/dev/null)
12
+ COMPREPLY=($(compgen -W "$versions --interactive" -- "$cur"))
13
+ }
14
+
15
+ _mnenv_global() {
16
+ _mnenv_use
17
+ }
18
+
19
+ _mnenv_local() {
20
+ _mnenv_use
21
+ }
22
+
23
+ _mnenv_uninstall() {
24
+ _mnenv_use
25
+ }
26
+
27
+ _mnenv() {
28
+ local cur="${COMP_WORDS[COMP_CWORD]}"
29
+ local prev="${COMP_WORDS[COMP_CWORD-1]}"
30
+ local commands="install use global local versions uninstall help gemfile snap homebrew chocolatey info list list-all version"
31
+
32
+ case "$prev" in
33
+ install) _mnenv_install ;;
34
+ use) _mnenv_use ;;
35
+ global) _mnenv_global ;;
36
+ local) _mnenv_local ;;
37
+ uninstall) _mnenv_uninstall ;;
38
+ *) COMPREPLY=($(compgen -W "$commands" -- "$cur")) ;;
39
+ esac
40
+ }
41
+
42
+ complete -F _mnenv mnenv
43
+
44
+ # Add ~/.mnenv/shims to PATH if not already present
45
+ if [[ ":$PATH:" != *":$HOME/.mnenv/shims:"* ]]; then
46
+ export PATH="$HOME/.mnenv/shims:$PATH"
47
+ fi
data/completions/fish ADDED
@@ -0,0 +1,29 @@
1
+ # Mnenv Fish completion
2
+
3
+ complete -c mnenv -f
4
+
5
+ complete -c mnenv -n __fish_use_subcommand -a install -d "Install a Metanorma version"
6
+ complete -c mnenv -n "__fish_seen_subcommand_from install" -l list -d "List all available versions"
7
+ complete -c mnenv -n "__fish_seen_subcommand_from install" -l interactive -s i -d "Interactive selection"
8
+ complete -c mnenv -n "__fish_seen_subcommand_from install" -a "(ls -1 ~/.mnenv/versions/)"
9
+
10
+ complete -c mnenv -n __fish_use_subcommand -a use -d "Set version for current shell"
11
+ complete -c mnenv -n "__fish_seen_subcommand_from use" -l interactive -s i -d "Interactive selection"
12
+ complete -c mnenv -n "__fish_seen_subcommand_from use" -a "(ls -1 ~/.mnenv/versions/)"
13
+
14
+ complete -c mnenv -n __fish_use_subcommand -a global -d "Set default version globally"
15
+ complete -c mnenv -n "__fish_seen_subcommand_from global" -l interactive -s i -d "Interactive selection"
16
+ complete -c mnenv -n "__fish_seen_subcommand_from global" -a "(ls -1 ~/.mnenv/versions/)"
17
+
18
+ complete -c mnenv -n __fish_use_subcommand -a local -d "Set version for current directory"
19
+ complete -c mnenv -n "__fish_seen_subcommand_from local" -l interactive -s i -d "Interactive selection"
20
+ complete -c mnenv -n "__fish_seen_subcommand_from local" -a "(ls -1 ~/.mnenv/versions/)"
21
+
22
+ complete -c mnenv -n __fish_use_subcommand -a versions -d "List installed versions"
23
+ complete -c mnenv -n __fish_use_subcommand -a uninstall -d "Uninstall a version"
24
+ complete -c mnenv -n "__fish_seen_subcommand_from uninstall" -a "(ls -1 ~/.mnenv/versions/)"
25
+
26
+ # Add ~/.mnenv/shims to PATH if not already present
27
+ if not contains -- ~/.mnenv/shims $PATH
28
+ set -gx PATH ~/.mnenv/shims $PATH
29
+ end
@@ -0,0 +1,94 @@
1
+ # Mnenv PowerShell completion
2
+ # Add this to your $PROFILE: . "$env:USERPROFILE\.mnenv\completions\powershell.ps1"
3
+
4
+ if ($null -eq (Get-Command Register-ArgumentCompleter -ErrorAction SilentlyContinue)) {
5
+ # PowerShell 5.0 or earlier - use old-style completion
6
+ function mnenvCompletion {
7
+ param($commandName, $wordToComplete, $cursorPosition)
8
+
9
+ $commands = @('install', 'use', 'global', 'local', 'versions', 'uninstall', 'help',
10
+ 'gemfile', 'snap', 'homebrew', 'chocolatey', 'info', 'list', 'list-all', 'version')
11
+
12
+ # Get installed versions
13
+ $versionsDir = Join-Path $env:USERPROFILE ".mnenv\versions"
14
+ if (Test-Path $versionsDir) {
15
+ $versions = Get-ChildItem $versionsDir -Directory | Select-Object -ExpandProperty Name
16
+ } else {
17
+ $versions = @()
18
+ }
19
+
20
+ # Command completion
21
+ $commandLine = $wordToComplete
22
+ $commandParts = $commandLine -split '\s+'
23
+ $commandCount = $commandParts.Count
24
+
25
+ if ($commandCount -eq 1 -or $commandLine.Trim().EndsWith(' ')) {
26
+ # Completing command
27
+ $commands | Where-Object { $_ -like "$wordToComplete*" }
28
+ }
29
+ # Subcommand completion
30
+ elseif ($commandCount -eq 2) {
31
+ $subcommand = $commandParts[1]
32
+
33
+ switch ($subcommand) {
34
+ { $_ -in @('install', 'use', 'global', 'local', 'uninstall') } {
35
+ $versions | Where-Object { $_ -like "$wordToComplete*" }
36
+ }
37
+ default {
38
+ @()
39
+ }
40
+ }
41
+ }
42
+ else {
43
+ @()
44
+ }
45
+ }
46
+
47
+ Register-ArgumentCompleter -CommandName 'mnenv' -ScriptBlock $function:mnenvCompletion
48
+ }
49
+ else {
50
+ # PowerShell 6+ - use modern completion
51
+ $script:block = {
52
+ param($wordToComplete, $commandAst, $cursorPosition)
53
+
54
+ $commands = @('install', 'use', 'global', 'local', 'versions', 'uninstall', 'help',
55
+ 'gemfile', 'snap', 'homebrew', 'chocolatey', 'info', 'list', 'list-all', 'version')
56
+
57
+ # Get installed versions
58
+ $versionsDir = Join-Path $env:USERPROFILE ".mnenv\versions"
59
+ if (Test-Path $versionsDir) {
60
+ $versions = Get-ChildItem $versionsDir -Directory | Select-Object -ExpandProperty Name
61
+ } else {
62
+ $versions = @()
63
+ }
64
+
65
+ # Command completion
66
+ if ($commandAst.CommandElements.Count -eq 1) {
67
+ $commands | Where-Object { $_ -like "$wordToComplete*" }
68
+ }
69
+ # Subcommand completion
70
+ elseif ($commandAst.CommandElements.Count -eq 2) {
71
+ $subcommand = $commandAst.CommandElements[1].Value
72
+
73
+ switch ($subcommand) {
74
+ { $_ -in @('install', 'use', 'global', 'local', 'uninstall') } {
75
+ $versions | Where-Object { $_ -like "$wordToComplete*" }
76
+ }
77
+ default {
78
+ @()
79
+ }
80
+ }
81
+ }
82
+ else {
83
+ @()
84
+ }
85
+ }
86
+
87
+ Register-ArgumentCompleter -CommandName 'mnenv' -ScriptBlock $script:block
88
+ }
89
+
90
+ # Add ~/.mnenv/shims to PATH if not already present
91
+ $shimsPath = Join-Path $env:USERPROFILE ".mnenv\shims"
92
+ if ($env:PATH -notlike "*$shimsPath*") {
93
+ $env:PATH = "$shimsPath;$env:PATH"
94
+ }
data/completions/zsh ADDED
@@ -0,0 +1,43 @@
1
+ # Mnenv Zsh completion
2
+
3
+ #compdef mnenv
4
+
5
+ _mnenv() {
6
+ local -a commands
7
+ commands=(
8
+ 'install:Install a Metanorma version'
9
+ 'use:Set Metanorma version for current shell session'
10
+ 'global:Set default Metanorma version globally'
11
+ 'local:Set Metanorma version for current directory'
12
+ 'versions:List all installed Metanorma versions'
13
+ 'uninstall:Uninstall a Metanorma version'
14
+ 'help:Show help'
15
+ 'gemfile:Gemfile-related commands'
16
+ 'snap:Snap-related commands'
17
+ 'homebrew:Homebrew-related commands'
18
+ 'chocolatey:Chocolatey-related commands'
19
+ 'info:Show information about a version'
20
+ 'list:List available versions'
21
+ 'list-all:List all available versions across sources'
22
+ 'version:Show mnenv version'
23
+ )
24
+
25
+ if (( CURRENT == 2 )); then
26
+ _describe 'command' commands
27
+ else
28
+ case "${words[2]}" in
29
+ install|use|global|local|uninstall)
30
+ local -a versions
31
+ versions=($(ls -1 ~/.mnenv/versions/ 2>/dev/null))
32
+ _describe 'version' versions
33
+ ;;
34
+ esac
35
+ fi
36
+ }
37
+
38
+ _mnenv "$@"
39
+
40
+ # Add ~/.mnenv/shims to PATH if not already present
41
+ if [[ ":$PATH:" != *":$HOME/.mnenv/shims:"* ]]; then
42
+ export PATH="$HOME/.mnenv/shims:$PATH"
43
+ fi
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'octokit'
4
+ require 'yaml'
5
+ require_relative 'models/binary_version'
6
+
7
+ module Mnenv
8
+ # Repository for Binary (packed-mn) GitHub releases
9
+ # Supports both cached YAML data (from versions repo) and live API fallback
10
+ class BinaryRepository
11
+ PACKED_MN_REPO = 'metanorma/packed-mn'
12
+
13
+ attr_reader :data_dir
14
+
15
+ def initialize(data_dir: nil, update: false)
16
+ @data_dir = data_dir || default_data_dir
17
+ @update = update
18
+ @versions_cache = {}
19
+ load
20
+ end
21
+
22
+ # Get all available binary versions
23
+ def all
24
+ # If cache is empty and not loaded from YAML, fall back to live API
25
+ @versions_cache = fetch_from_api if @versions_cache.empty? && !@loaded_from_yaml
26
+ @versions_cache.values.sort.reverse
27
+ end
28
+
29
+ # Find a specific version
30
+ def find(version_number)
31
+ version_number = normalize_version(version_number)
32
+ all.find { |v| v.version == version_number }
33
+ end
34
+
35
+ # Check if a version is available for the current platform
36
+ def available_for_platform?(version_number)
37
+ version = find(version_number)
38
+ return false unless version
39
+
40
+ platform = detect_platform
41
+ binary_name = "metanorma-#{platform}"
42
+ version.assets.any? { |a| a == binary_name || a.include?(platform) }
43
+ end
44
+
45
+ # Get the latest version
46
+ def latest
47
+ all.first
48
+ end
49
+
50
+ # Count of available versions
51
+ def count
52
+ @versions_cache.size
53
+ end
54
+
55
+ private
56
+
57
+ # Create Octokit client with GitHub token if available
58
+ # Uses GITHUB_TOKEN (GitHub Actions) or GH_TOKEN (GitHub CLI) for higher rate limits
59
+ # Falls back to unauthenticated client (60 req/hour) if no token is available
60
+ def client
61
+ @client ||= begin
62
+ token = github_token
63
+ if token
64
+ Octokit::Client.new(access_token: token)
65
+ else
66
+ Octokit::Client.new
67
+ end
68
+ end
69
+ end
70
+
71
+ # Detect GitHub token from environment variables
72
+ # Priority: GITHUB_TOKEN (GitHub Actions), GH_TOKEN (GitHub CLI)
73
+ def github_token
74
+ ENV['GITHUB_TOKEN'] || ENV['GH_TOKEN']
75
+ end
76
+
77
+ def default_data_dir
78
+ # Check if CLI data_dir is specified
79
+ if defined?(Mnenv::Cli) && Mnenv::Cli.data_dir
80
+ File.join(Mnenv::Cli.data_dir, 'binary')
81
+ else
82
+ # Use versions manager to get data path
83
+ require_relative 'versions_manager'
84
+ data_path = Mnenv::Repository.versions_manager.ensure_versions_data(update: @update)
85
+ File.join(data_path, 'binary')
86
+ end
87
+ end
88
+
89
+ def load
90
+ versions_file = File.join(@data_dir, 'versions.yaml')
91
+
92
+ if File.exist?(versions_file)
93
+ @loaded_from_yaml = true
94
+ data = YAML.safe_load(File.read(versions_file), permitted_classes: [Time, Symbol, Date])
95
+ return unless data && data['versions']
96
+
97
+ data['versions'].each do |version_hash|
98
+ version = parse_cached_version(version_hash)
99
+ @versions_cache[version.version] = version if version
100
+ end
101
+ else
102
+ @loaded_from_yaml = false
103
+ end
104
+ rescue StandardError => e
105
+ warn "Warning: Failed to load binary versions from cache: #{e.message}"
106
+ @loaded_from_yaml = false
107
+ end
108
+
109
+ def parse_cached_version(hash)
110
+ return nil unless hash['version']
111
+
112
+ # Extract assets from platforms array (for backward compatibility)
113
+ assets = (hash['platforms'] || []).map { |p| p['filename'] }.compact
114
+
115
+ # Store full platforms data including URLs
116
+ platforms = hash['platforms'] || []
117
+
118
+ BinaryVersion.new(
119
+ version: hash['version'],
120
+ display_name: hash['version'],
121
+ published_at: parse_date(hash['published_at']),
122
+ parsed_at: parse_date(hash['parsed_at']),
123
+ metadata: {
124
+ 'tag_name' => hash['tag_name'] || "v#{hash['version']}",
125
+ 'html_url' => hash['html_url'],
126
+ 'assets' => assets,
127
+ 'platforms' => platforms
128
+ }
129
+ )
130
+ end
131
+
132
+ def fetch_from_api
133
+ releases = fetch_releases
134
+ result = {}
135
+ releases.each do |release|
136
+ version = parse_release(release)
137
+ result[version.version] = version if version
138
+ end
139
+ result
140
+ end
141
+
142
+ def fetch_releases
143
+ client.releases(PACKED_MN_REPO)
144
+ rescue Octokit::Error => e
145
+ warn "Warning: Failed to fetch binary releases: #{e.message}"
146
+ []
147
+ end
148
+
149
+ def parse_release(release)
150
+ return nil unless release.tag_name =~ /^v(\d+\.\d+\.\d+)/
151
+
152
+ version = release.tag_name.sub(/^v/, '')
153
+ published_at = release.published_at
154
+
155
+ BinaryVersion.new(
156
+ version: version,
157
+ display_name: version,
158
+ published_at: published_at,
159
+ parsed_at: Time.now.utc,
160
+ metadata: {
161
+ 'tag_name' => release.tag_name,
162
+ 'html_url' => release.html_url,
163
+ 'assets' => release.assets.map(&:name)
164
+ }
165
+ )
166
+ end
167
+
168
+ def parse_date(date_string)
169
+ return nil unless date_string
170
+
171
+ Time.parse(date_string)
172
+ rescue ArgumentError
173
+ nil
174
+ end
175
+
176
+ def detect_platform
177
+ case RbConfig::CONFIG['host_os']
178
+ when /linux/ then 'linux'
179
+ when /darwin/ then 'macos'
180
+ when /mswin|mingw|cygwin/ then 'windows'
181
+ else 'unknown'
182
+ end
183
+ end
184
+
185
+ def normalize_version(version)
186
+ version.sub(/^v/, '')
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mnenv
4
+ module Chocolatey
5
+ autoload :Fetcher, 'mnenv/chocolatey/fetcher'
6
+ end
7
+ end