mnenv 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) 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 +42 -0
  22. data/lib/mnenv/commands/version_command.rb +213 -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 +17 -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/repository.rb +50 -35
  44. data/lib/mnenv/resolver +72 -0
  45. data/lib/mnenv/shells/base.rb +32 -0
  46. data/lib/mnenv/shells/bash.rb +72 -0
  47. data/lib/mnenv/shells/cmd.rb +108 -0
  48. data/lib/mnenv/shells/factory.rb +82 -0
  49. data/lib/mnenv/shells/power_shell.rb +110 -0
  50. data/lib/mnenv/shim_manager.rb +121 -0
  51. data/lib/mnenv/snap.rb +7 -0
  52. data/lib/mnenv/snap_repository.rb +2 -19
  53. data/lib/mnenv/source_registry.rb +69 -0
  54. data/lib/mnenv/version.rb +1 -1
  55. data/lib/mnenv/versions_manager.rb +92 -0
  56. data/lib/mnenv.rb +3 -0
  57. data/mnenv.gemspec +4 -1
  58. data/scripts/cross-source-switching-test.sh +214 -0
  59. data/scripts/integration-test.sh +89 -0
  60. data/scripts/version-switching-test.sh +151 -0
  61. metadata +82 -247
  62. data/data/chocolatey/versions.yaml +0 -812
  63. data/data/gemfile/v1.1.6/Gemfile +0 -4
  64. data/data/gemfile/v1.1.6/Gemfile.lock.archived +0 -232
  65. data/data/gemfile/v1.1.7/Gemfile +0 -4
  66. data/data/gemfile/v1.1.7/Gemfile.lock.archived +0 -235
  67. data/data/gemfile/v1.1.8/Gemfile +0 -4
  68. data/data/gemfile/v1.1.8/Gemfile.lock.archived +0 -238
  69. data/data/gemfile/v1.10.0/Gemfile +0 -5
  70. data/data/gemfile/v1.10.0/Gemfile.lock.archived +0 -930
  71. data/data/gemfile/v1.10.1/Gemfile +0 -5
  72. data/data/gemfile/v1.10.1/Gemfile.lock.archived +0 -929
  73. data/data/gemfile/v1.10.10/Gemfile +0 -5
  74. data/data/gemfile/v1.10.10/Gemfile.lock.archived +0 -973
  75. data/data/gemfile/v1.10.11/Gemfile +0 -5
  76. data/data/gemfile/v1.10.11/Gemfile.lock.archived +0 -975
  77. data/data/gemfile/v1.10.2/Gemfile +0 -5
  78. data/data/gemfile/v1.10.2/Gemfile.lock.archived +0 -939
  79. data/data/gemfile/v1.10.3/Gemfile +0 -5
  80. data/data/gemfile/v1.10.3/Gemfile.lock.archived +0 -946
  81. data/data/gemfile/v1.10.5/Gemfile +0 -5
  82. data/data/gemfile/v1.10.5/Gemfile.lock.archived +0 -958
  83. data/data/gemfile/v1.10.6/Gemfile +0 -5
  84. data/data/gemfile/v1.10.6/Gemfile.lock.archived +0 -969
  85. data/data/gemfile/v1.10.7/Gemfile +0 -5
  86. data/data/gemfile/v1.10.7/Gemfile.lock.archived +0 -969
  87. data/data/gemfile/v1.10.8/Gemfile +0 -5
  88. data/data/gemfile/v1.10.8/Gemfile.lock.archived +0 -968
  89. data/data/gemfile/v1.10.9/Gemfile +0 -5
  90. data/data/gemfile/v1.10.9/Gemfile.lock.archived +0 -972
  91. data/data/gemfile/v1.11.0/Gemfile +0 -5
  92. data/data/gemfile/v1.11.0/Gemfile.lock.archived +0 -971
  93. data/data/gemfile/v1.11.1/Gemfile +0 -5
  94. data/data/gemfile/v1.11.1/Gemfile.lock.archived +0 -975
  95. data/data/gemfile/v1.11.4/Gemfile +0 -5
  96. data/data/gemfile/v1.11.4/Gemfile.lock.archived +0 -1046
  97. data/data/gemfile/v1.11.5/Gemfile +0 -5
  98. data/data/gemfile/v1.11.5/Gemfile.lock.archived +0 -1047
  99. data/data/gemfile/v1.12.10/Gemfile +0 -3
  100. data/data/gemfile/v1.12.10/Gemfile.lock.archived +0 -1073
  101. data/data/gemfile/v1.12.3/Gemfile +0 -3
  102. data/data/gemfile/v1.12.3/Gemfile.lock.archived +0 -1050
  103. data/data/gemfile/v1.12.4/Gemfile +0 -3
  104. data/data/gemfile/v1.12.4/Gemfile.lock.archived +0 -1056
  105. data/data/gemfile/v1.12.5/Gemfile +0 -3
  106. data/data/gemfile/v1.12.5/Gemfile.lock.archived +0 -1054
  107. data/data/gemfile/v1.12.6/Gemfile +0 -3
  108. data/data/gemfile/v1.12.6/Gemfile.lock.archived +0 -1056
  109. data/data/gemfile/v1.12.8/Gemfile +0 -3
  110. data/data/gemfile/v1.12.8/Gemfile.lock.archived +0 -1063
  111. data/data/gemfile/v1.13.0/Gemfile +0 -3
  112. data/data/gemfile/v1.13.0/Gemfile.lock.archived +0 -1074
  113. data/data/gemfile/v1.13.2/Gemfile +0 -3
  114. data/data/gemfile/v1.13.2/Gemfile.lock.archived +0 -899
  115. data/data/gemfile/v1.13.3/Gemfile +0 -3
  116. data/data/gemfile/v1.13.3/Gemfile.lock.archived +0 -938
  117. data/data/gemfile/v1.13.4/Gemfile +0 -3
  118. data/data/gemfile/v1.13.4/Gemfile.lock.archived +0 -938
  119. data/data/gemfile/v1.13.5/Gemfile +0 -3
  120. data/data/gemfile/v1.13.5/Gemfile.lock.archived +0 -944
  121. data/data/gemfile/v1.13.7/Gemfile +0 -3
  122. data/data/gemfile/v1.13.7/Gemfile.lock.archived +0 -944
  123. data/data/gemfile/v1.13.8/Gemfile +0 -3
  124. data/data/gemfile/v1.13.8/Gemfile.lock.archived +0 -944
  125. data/data/gemfile/v1.13.9/Gemfile +0 -3
  126. data/data/gemfile/v1.13.9/Gemfile.lock.archived +0 -956
  127. data/data/gemfile/v1.14.3/Gemfile +0 -3
  128. data/data/gemfile/v1.14.3/Gemfile.lock.archived +0 -950
  129. data/data/gemfile/v1.2.12/Gemfile +0 -3
  130. data/data/gemfile/v1.2.12/Gemfile.lock.archived +0 -283
  131. data/data/gemfile/v1.2.2/Gemfile +0 -4
  132. data/data/gemfile/v1.2.2/Gemfile.lock.archived +0 -224
  133. data/data/gemfile/v1.2.3/Gemfile +0 -4
  134. data/data/gemfile/v1.2.3/Gemfile.lock.archived +0 -231
  135. data/data/gemfile/v1.2.6/Gemfile +0 -4
  136. data/data/gemfile/v1.2.6/Gemfile.lock.archived +0 -239
  137. data/data/gemfile/v1.2.8/Gemfile +0 -4
  138. data/data/gemfile/v1.2.8/Gemfile.lock.archived +0 -233
  139. data/data/gemfile/v1.2.9/Gemfile +0 -4
  140. data/data/gemfile/v1.2.9/Gemfile.lock.archived +0 -245
  141. data/data/gemfile/v1.3.1/Gemfile +0 -3
  142. data/data/gemfile/v1.3.1/Gemfile.lock.archived +0 -296
  143. data/data/gemfile/v1.3.2/Gemfile +0 -3
  144. data/data/gemfile/v1.3.2/Gemfile.lock.archived +0 -296
  145. data/data/gemfile/v1.3.4/Gemfile +0 -3
  146. data/data/gemfile/v1.3.4/Gemfile.lock.archived +0 -284
  147. data/data/gemfile/v1.3.5/Gemfile +0 -3
  148. data/data/gemfile/v1.3.5/Gemfile.lock.archived +0 -284
  149. data/data/gemfile/v1.3.6/Gemfile +0 -3
  150. data/data/gemfile/v1.3.6/Gemfile.lock.archived +0 -286
  151. data/data/gemfile/v1.3.9/Gemfile +0 -3
  152. data/data/gemfile/v1.3.9/Gemfile.lock.archived +0 -334
  153. data/data/gemfile/v1.4.0/Gemfile +0 -3
  154. data/data/gemfile/v1.4.0/Gemfile.lock.archived +0 -330
  155. data/data/gemfile/v1.4.10/Gemfile +0 -4
  156. data/data/gemfile/v1.4.10/Gemfile.lock.archived +0 -461
  157. data/data/gemfile/v1.4.11/Gemfile +0 -4
  158. data/data/gemfile/v1.4.11/Gemfile.lock.archived +0 -452
  159. data/data/gemfile/v1.4.12/Gemfile +0 -4
  160. data/data/gemfile/v1.4.12/Gemfile.lock.archived +0 -452
  161. data/data/gemfile/v1.4.13/Gemfile +0 -4
  162. data/data/gemfile/v1.4.13/Gemfile.lock.archived +0 -455
  163. data/data/gemfile/v1.4.14/Gemfile +0 -4
  164. data/data/gemfile/v1.4.14/Gemfile.lock.archived +0 -456
  165. data/data/gemfile/v1.4.18/Gemfile +0 -3
  166. data/data/gemfile/v1.4.18/Gemfile.lock.archived +0 -486
  167. data/data/gemfile/v1.4.3/Gemfile +0 -3
  168. data/data/gemfile/v1.4.3/Gemfile.lock.archived +0 -339
  169. data/data/gemfile/v1.4.4/Gemfile +0 -3
  170. data/data/gemfile/v1.4.4/Gemfile.lock.archived +0 -339
  171. data/data/gemfile/v1.4.5/Gemfile +0 -3
  172. data/data/gemfile/v1.4.5/Gemfile.lock.archived +0 -348
  173. data/data/gemfile/v1.4.6/Gemfile +0 -3
  174. data/data/gemfile/v1.4.6/Gemfile.lock.archived +0 -357
  175. data/data/gemfile/v1.4.7/Gemfile +0 -3
  176. data/data/gemfile/v1.4.7/Gemfile.lock.archived +0 -391
  177. data/data/gemfile/v1.4.8/Gemfile +0 -3
  178. data/data/gemfile/v1.4.8/Gemfile.lock.archived +0 -445
  179. data/data/gemfile/v1.4.9/Gemfile +0 -3
  180. data/data/gemfile/v1.4.9/Gemfile.lock.archived +0 -448
  181. data/data/gemfile/v1.5.0/Gemfile +0 -3
  182. data/data/gemfile/v1.5.0/Gemfile.lock.archived +0 -478
  183. data/data/gemfile/v1.5.10/Gemfile +0 -3
  184. data/data/gemfile/v1.5.10/Gemfile.lock.archived +0 -668
  185. data/data/gemfile/v1.5.11/Gemfile +0 -3
  186. data/data/gemfile/v1.5.11/Gemfile.lock.archived +0 -668
  187. data/data/gemfile/v1.5.15/Gemfile +0 -3
  188. data/data/gemfile/v1.5.15/Gemfile.lock.archived +0 -686
  189. data/data/gemfile/v1.5.16/Gemfile +0 -3
  190. data/data/gemfile/v1.5.16/Gemfile.lock.archived +0 -684
  191. data/data/gemfile/v1.5.17/Gemfile +0 -3
  192. data/data/gemfile/v1.5.17/Gemfile.lock.archived +0 -684
  193. data/data/gemfile/v1.5.18/Gemfile +0 -5
  194. data/data/gemfile/v1.5.18/Gemfile.lock.archived +0 -691
  195. data/data/gemfile/v1.5.19/Gemfile +0 -5
  196. data/data/gemfile/v1.5.19/Gemfile.lock.archived +0 -703
  197. data/data/gemfile/v1.5.20/Gemfile +0 -5
  198. data/data/gemfile/v1.5.20/Gemfile.lock.archived +0 -703
  199. data/data/gemfile/v1.5.21/Gemfile +0 -5
  200. data/data/gemfile/v1.5.21/Gemfile.lock.archived +0 -707
  201. data/data/gemfile/v1.5.22/Gemfile +0 -5
  202. data/data/gemfile/v1.5.22/Gemfile.lock.archived +0 -707
  203. data/data/gemfile/v1.5.23/Gemfile +0 -5
  204. data/data/gemfile/v1.5.23/Gemfile.lock.archived +0 -711
  205. data/data/gemfile/v1.5.24/Gemfile +0 -5
  206. data/data/gemfile/v1.5.24/Gemfile.lock.archived +0 -711
  207. data/data/gemfile/v1.5.3/Gemfile +0 -3
  208. data/data/gemfile/v1.5.3/Gemfile.lock.archived +0 -651
  209. data/data/gemfile/v1.5.4/Gemfile +0 -3
  210. data/data/gemfile/v1.5.4/Gemfile.lock.archived +0 -657
  211. data/data/gemfile/v1.5.5/Gemfile +0 -3
  212. data/data/gemfile/v1.5.5/Gemfile.lock.archived +0 -657
  213. data/data/gemfile/v1.5.6/Gemfile +0 -3
  214. data/data/gemfile/v1.5.6/Gemfile.lock.archived +0 -657
  215. data/data/gemfile/v1.5.7/Gemfile +0 -3
  216. data/data/gemfile/v1.5.7/Gemfile.lock.archived +0 -657
  217. data/data/gemfile/v1.5.8/Gemfile +0 -3
  218. data/data/gemfile/v1.5.8/Gemfile.lock.archived +0 -655
  219. data/data/gemfile/v1.5.9/Gemfile +0 -3
  220. data/data/gemfile/v1.5.9/Gemfile.lock.archived +0 -656
  221. data/data/gemfile/v1.6.1/Gemfile +0 -5
  222. data/data/gemfile/v1.6.1/Gemfile.lock.archived +0 -721
  223. data/data/gemfile/v1.6.10/Gemfile +0 -5
  224. data/data/gemfile/v1.6.10/Gemfile.lock.archived +0 -744
  225. data/data/gemfile/v1.6.11/Gemfile +0 -5
  226. data/data/gemfile/v1.6.11/Gemfile.lock.archived +0 -744
  227. data/data/gemfile/v1.6.12/Gemfile +0 -5
  228. data/data/gemfile/v1.6.12/Gemfile.lock.archived +0 -745
  229. data/data/gemfile/v1.6.13/Gemfile +0 -5
  230. data/data/gemfile/v1.6.13/Gemfile.lock.archived +0 -745
  231. data/data/gemfile/v1.6.14/Gemfile +0 -5
  232. data/data/gemfile/v1.6.14/Gemfile.lock.archived +0 -754
  233. data/data/gemfile/v1.6.15/Gemfile +0 -5
  234. data/data/gemfile/v1.6.15/Gemfile.lock.archived +0 -757
  235. data/data/gemfile/v1.6.2/Gemfile +0 -5
  236. data/data/gemfile/v1.6.2/Gemfile.lock.archived +0 -718
  237. data/data/gemfile/v1.6.3/Gemfile +0 -5
  238. data/data/gemfile/v1.6.3/Gemfile.lock.archived +0 -728
  239. data/data/gemfile/v1.6.4/Gemfile +0 -5
  240. data/data/gemfile/v1.6.4/Gemfile.lock.archived +0 -730
  241. data/data/gemfile/v1.6.5/Gemfile +0 -5
  242. data/data/gemfile/v1.6.5/Gemfile.lock.archived +0 -733
  243. data/data/gemfile/v1.6.6/Gemfile +0 -5
  244. data/data/gemfile/v1.6.6/Gemfile.lock.archived +0 -733
  245. data/data/gemfile/v1.6.7/Gemfile +0 -5
  246. data/data/gemfile/v1.6.7/Gemfile.lock.archived +0 -733
  247. data/data/gemfile/v1.6.9/Gemfile +0 -5
  248. data/data/gemfile/v1.6.9/Gemfile.lock.archived +0 -744
  249. data/data/gemfile/v1.7.0/Gemfile +0 -5
  250. data/data/gemfile/v1.7.0/Gemfile.lock.archived +0 -750
  251. data/data/gemfile/v1.7.1/Gemfile +0 -5
  252. data/data/gemfile/v1.7.1/Gemfile.lock.archived +0 -750
  253. data/data/gemfile/v1.7.2/Gemfile +0 -5
  254. data/data/gemfile/v1.7.2/Gemfile.lock.archived +0 -747
  255. data/data/gemfile/v1.7.3/Gemfile +0 -5
  256. data/data/gemfile/v1.7.3/Gemfile.lock.archived +0 -755
  257. data/data/gemfile/v1.7.4/Gemfile +0 -5
  258. data/data/gemfile/v1.7.4/Gemfile.lock.archived +0 -756
  259. data/data/gemfile/v1.7.5/Gemfile +0 -5
  260. data/data/gemfile/v1.7.5/Gemfile.lock.archived +0 -759
  261. data/data/gemfile/v1.7.6/Gemfile +0 -5
  262. data/data/gemfile/v1.7.6/Gemfile.lock.archived +0 -768
  263. data/data/gemfile/v1.8.10/Gemfile +0 -5
  264. data/data/gemfile/v1.8.10/Gemfile.lock.archived +0 -792
  265. data/data/gemfile/v1.8.11/Gemfile +0 -5
  266. data/data/gemfile/v1.8.11/Gemfile.lock.archived +0 -862
  267. data/data/gemfile/v1.8.3/Gemfile +0 -5
  268. data/data/gemfile/v1.8.3/Gemfile.lock.archived +0 -773
  269. data/data/gemfile/v1.8.4/Gemfile +0 -5
  270. data/data/gemfile/v1.8.4/Gemfile.lock.archived +0 -768
  271. data/data/gemfile/v1.8.5/Gemfile +0 -5
  272. data/data/gemfile/v1.8.5/Gemfile.lock.archived +0 -768
  273. data/data/gemfile/v1.8.6/Gemfile +0 -5
  274. data/data/gemfile/v1.8.6/Gemfile.lock.archived +0 -777
  275. data/data/gemfile/v1.8.7/Gemfile +0 -5
  276. data/data/gemfile/v1.8.7/Gemfile.lock.archived +0 -777
  277. data/data/gemfile/v1.8.8/Gemfile +0 -5
  278. data/data/gemfile/v1.8.8/Gemfile.lock.archived +0 -778
  279. data/data/gemfile/v1.8.9/Gemfile +0 -5
  280. data/data/gemfile/v1.8.9/Gemfile.lock.archived +0 -775
  281. data/data/gemfile/v1.9.0/Gemfile +0 -5
  282. data/data/gemfile/v1.9.0/Gemfile.lock.archived +0 -871
  283. data/data/gemfile/v1.9.1/Gemfile +0 -5
  284. data/data/gemfile/v1.9.1/Gemfile.lock.archived +0 -906
  285. data/data/gemfile/v1.9.2/Gemfile +0 -5
  286. data/data/gemfile/v1.9.2/Gemfile.lock.archived +0 -898
  287. data/data/gemfile/v1.9.3/Gemfile +0 -5
  288. data/data/gemfile/v1.9.3/Gemfile.lock.archived +0 -898
  289. data/data/gemfile/v1.9.4/Gemfile +0 -5
  290. data/data/gemfile/v1.9.4/Gemfile.lock.archived +0 -901
  291. data/data/gemfile/v1.9.5/Gemfile +0 -5
  292. data/data/gemfile/v1.9.5/Gemfile.lock.archived +0 -903
  293. data/data/gemfile/v1.9.6/Gemfile +0 -5
  294. data/data/gemfile/v1.9.6/Gemfile.lock.archived +0 -900
  295. data/data/gemfile/v1.9.7/Gemfile +0 -5
  296. data/data/gemfile/v1.9.7/Gemfile.lock.archived +0 -922
  297. data/data/gemfile/v1.9.8/Gemfile +0 -5
  298. data/data/gemfile/v1.9.8/Gemfile.lock.archived +0 -933
  299. data/data/gemfile/versions.yaml +0 -751
  300. data/data/homebrew/versions.yaml +0 -567
  301. data/data/snap/github_tags.json +0 -42
  302. data/data/snap/versions.yaml +0 -589
  303. 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