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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/PROPOSAL.md +197 -0
- data/README.adoc +168 -461
- data/Rakefile +7 -4
- data/bin/Install-Mnenv.ps1 +145 -0
- data/bin/mnenv-installer +72 -0
- data/completions/bash +47 -0
- data/completions/fish +29 -0
- data/completions/powershell.ps1 +94 -0
- data/completions/zsh +43 -0
- data/lib/mnenv/binary_repository.rb +189 -0
- data/lib/mnenv/chocolatey.rb +7 -0
- data/lib/mnenv/cli.rb +110 -10
- data/lib/mnenv/commands/available_command.rb +169 -0
- data/lib/mnenv/commands/chocolatey_command.rb +4 -5
- data/lib/mnenv/commands/gemfile_command.rb +4 -5
- data/lib/mnenv/commands/homebrew_command.rb +4 -5
- data/lib/mnenv/commands/install_command.rb +234 -0
- data/lib/mnenv/commands/snap_command.rb +5 -7
- data/lib/mnenv/commands/uninstall_command.rb +111 -0
- data/lib/mnenv/commands/version_command.rb +167 -0
- data/lib/mnenv/commands.rb +9 -4
- data/lib/mnenv/gemfile/extractor.rb +10 -3
- data/lib/mnenv/gemfile.rb +8 -0
- data/lib/mnenv/gemfile_repository.rb +0 -2
- data/lib/mnenv/homebrew.rb +7 -0
- data/lib/mnenv/installer/base.rb +62 -0
- data/lib/mnenv/installer/factory.rb +46 -0
- data/lib/mnenv/installer.rb +12 -0
- data/lib/mnenv/installers/binary_installer.rb +242 -0
- data/lib/mnenv/installers/gemfile_installer.rb +76 -0
- data/lib/mnenv/json_formatter.rb +3 -13
- data/lib/mnenv/logger.rb +9 -1
- data/lib/mnenv/models/binary_version.rb +78 -0
- data/lib/mnenv/models/chocolatey_version.rb +7 -0
- data/lib/mnenv/models/gemfile_version.rb +19 -5
- data/lib/mnenv/models/homebrew_version.rb +7 -0
- data/lib/mnenv/models/snap_version.rb +8 -0
- data/lib/mnenv/models/version.rb +16 -0
- data/lib/mnenv/models.rb +7 -5
- data/lib/mnenv/paths.rb +69 -0
- data/lib/mnenv/platform_detector.rb +109 -0
- data/lib/mnenv/repository.rb +50 -35
- data/lib/mnenv/resolver +72 -0
- data/lib/mnenv/shells/base.rb +32 -0
- data/lib/mnenv/shells/bash.rb +72 -0
- data/lib/mnenv/shells/cmd.rb +108 -0
- data/lib/mnenv/shells/factory.rb +82 -0
- data/lib/mnenv/shells/power_shell.rb +110 -0
- data/lib/mnenv/shim_manager.rb +121 -0
- data/lib/mnenv/snap.rb +7 -0
- data/lib/mnenv/snap_repository.rb +2 -19
- data/lib/mnenv/source_registry.rb +69 -0
- data/lib/mnenv/sources.rb +46 -0
- data/lib/mnenv/version.rb +1 -1
- data/lib/mnenv/version_resolver.rb +108 -0
- data/lib/mnenv/versions_manager.rb +92 -0
- data/lib/mnenv.rb +6 -0
- data/mnenv.gemspec +4 -1
- data/scripts/cross-source-switching-test.sh +214 -0
- data/scripts/integration-test.sh +89 -0
- data/scripts/version-switching-test.sh +151 -0
- metadata +85 -247
- data/data/chocolatey/versions.yaml +0 -812
- data/data/gemfile/v1.1.6/Gemfile +0 -4
- data/data/gemfile/v1.1.6/Gemfile.lock.archived +0 -232
- data/data/gemfile/v1.1.7/Gemfile +0 -4
- data/data/gemfile/v1.1.7/Gemfile.lock.archived +0 -235
- data/data/gemfile/v1.1.8/Gemfile +0 -4
- data/data/gemfile/v1.1.8/Gemfile.lock.archived +0 -238
- data/data/gemfile/v1.10.0/Gemfile +0 -5
- data/data/gemfile/v1.10.0/Gemfile.lock.archived +0 -930
- data/data/gemfile/v1.10.1/Gemfile +0 -5
- data/data/gemfile/v1.10.1/Gemfile.lock.archived +0 -929
- data/data/gemfile/v1.10.10/Gemfile +0 -5
- data/data/gemfile/v1.10.10/Gemfile.lock.archived +0 -973
- data/data/gemfile/v1.10.11/Gemfile +0 -5
- data/data/gemfile/v1.10.11/Gemfile.lock.archived +0 -975
- data/data/gemfile/v1.10.2/Gemfile +0 -5
- data/data/gemfile/v1.10.2/Gemfile.lock.archived +0 -939
- data/data/gemfile/v1.10.3/Gemfile +0 -5
- data/data/gemfile/v1.10.3/Gemfile.lock.archived +0 -946
- data/data/gemfile/v1.10.5/Gemfile +0 -5
- data/data/gemfile/v1.10.5/Gemfile.lock.archived +0 -958
- data/data/gemfile/v1.10.6/Gemfile +0 -5
- data/data/gemfile/v1.10.6/Gemfile.lock.archived +0 -969
- data/data/gemfile/v1.10.7/Gemfile +0 -5
- data/data/gemfile/v1.10.7/Gemfile.lock.archived +0 -969
- data/data/gemfile/v1.10.8/Gemfile +0 -5
- data/data/gemfile/v1.10.8/Gemfile.lock.archived +0 -968
- data/data/gemfile/v1.10.9/Gemfile +0 -5
- data/data/gemfile/v1.10.9/Gemfile.lock.archived +0 -972
- data/data/gemfile/v1.11.0/Gemfile +0 -5
- data/data/gemfile/v1.11.0/Gemfile.lock.archived +0 -971
- data/data/gemfile/v1.11.1/Gemfile +0 -5
- data/data/gemfile/v1.11.1/Gemfile.lock.archived +0 -975
- data/data/gemfile/v1.11.4/Gemfile +0 -5
- data/data/gemfile/v1.11.4/Gemfile.lock.archived +0 -1046
- data/data/gemfile/v1.11.5/Gemfile +0 -5
- data/data/gemfile/v1.11.5/Gemfile.lock.archived +0 -1047
- data/data/gemfile/v1.12.10/Gemfile +0 -3
- data/data/gemfile/v1.12.10/Gemfile.lock.archived +0 -1073
- data/data/gemfile/v1.12.3/Gemfile +0 -3
- data/data/gemfile/v1.12.3/Gemfile.lock.archived +0 -1050
- data/data/gemfile/v1.12.4/Gemfile +0 -3
- data/data/gemfile/v1.12.4/Gemfile.lock.archived +0 -1056
- data/data/gemfile/v1.12.5/Gemfile +0 -3
- data/data/gemfile/v1.12.5/Gemfile.lock.archived +0 -1054
- data/data/gemfile/v1.12.6/Gemfile +0 -3
- data/data/gemfile/v1.12.6/Gemfile.lock.archived +0 -1056
- data/data/gemfile/v1.12.8/Gemfile +0 -3
- data/data/gemfile/v1.12.8/Gemfile.lock.archived +0 -1063
- data/data/gemfile/v1.13.0/Gemfile +0 -3
- data/data/gemfile/v1.13.0/Gemfile.lock.archived +0 -1074
- data/data/gemfile/v1.13.2/Gemfile +0 -3
- data/data/gemfile/v1.13.2/Gemfile.lock.archived +0 -899
- data/data/gemfile/v1.13.3/Gemfile +0 -3
- data/data/gemfile/v1.13.3/Gemfile.lock.archived +0 -938
- data/data/gemfile/v1.13.4/Gemfile +0 -3
- data/data/gemfile/v1.13.4/Gemfile.lock.archived +0 -938
- data/data/gemfile/v1.13.5/Gemfile +0 -3
- data/data/gemfile/v1.13.5/Gemfile.lock.archived +0 -944
- data/data/gemfile/v1.13.7/Gemfile +0 -3
- data/data/gemfile/v1.13.7/Gemfile.lock.archived +0 -944
- data/data/gemfile/v1.13.8/Gemfile +0 -3
- data/data/gemfile/v1.13.8/Gemfile.lock.archived +0 -944
- data/data/gemfile/v1.13.9/Gemfile +0 -3
- data/data/gemfile/v1.13.9/Gemfile.lock.archived +0 -956
- data/data/gemfile/v1.14.3/Gemfile +0 -3
- data/data/gemfile/v1.14.3/Gemfile.lock.archived +0 -950
- data/data/gemfile/v1.2.12/Gemfile +0 -3
- data/data/gemfile/v1.2.12/Gemfile.lock.archived +0 -283
- data/data/gemfile/v1.2.2/Gemfile +0 -4
- data/data/gemfile/v1.2.2/Gemfile.lock.archived +0 -224
- data/data/gemfile/v1.2.3/Gemfile +0 -4
- data/data/gemfile/v1.2.3/Gemfile.lock.archived +0 -231
- data/data/gemfile/v1.2.6/Gemfile +0 -4
- data/data/gemfile/v1.2.6/Gemfile.lock.archived +0 -239
- data/data/gemfile/v1.2.8/Gemfile +0 -4
- data/data/gemfile/v1.2.8/Gemfile.lock.archived +0 -233
- data/data/gemfile/v1.2.9/Gemfile +0 -4
- data/data/gemfile/v1.2.9/Gemfile.lock.archived +0 -245
- data/data/gemfile/v1.3.1/Gemfile +0 -3
- data/data/gemfile/v1.3.1/Gemfile.lock.archived +0 -296
- data/data/gemfile/v1.3.2/Gemfile +0 -3
- data/data/gemfile/v1.3.2/Gemfile.lock.archived +0 -296
- data/data/gemfile/v1.3.4/Gemfile +0 -3
- data/data/gemfile/v1.3.4/Gemfile.lock.archived +0 -284
- data/data/gemfile/v1.3.5/Gemfile +0 -3
- data/data/gemfile/v1.3.5/Gemfile.lock.archived +0 -284
- data/data/gemfile/v1.3.6/Gemfile +0 -3
- data/data/gemfile/v1.3.6/Gemfile.lock.archived +0 -286
- data/data/gemfile/v1.3.9/Gemfile +0 -3
- data/data/gemfile/v1.3.9/Gemfile.lock.archived +0 -334
- data/data/gemfile/v1.4.0/Gemfile +0 -3
- data/data/gemfile/v1.4.0/Gemfile.lock.archived +0 -330
- data/data/gemfile/v1.4.10/Gemfile +0 -4
- data/data/gemfile/v1.4.10/Gemfile.lock.archived +0 -461
- data/data/gemfile/v1.4.11/Gemfile +0 -4
- data/data/gemfile/v1.4.11/Gemfile.lock.archived +0 -452
- data/data/gemfile/v1.4.12/Gemfile +0 -4
- data/data/gemfile/v1.4.12/Gemfile.lock.archived +0 -452
- data/data/gemfile/v1.4.13/Gemfile +0 -4
- data/data/gemfile/v1.4.13/Gemfile.lock.archived +0 -455
- data/data/gemfile/v1.4.14/Gemfile +0 -4
- data/data/gemfile/v1.4.14/Gemfile.lock.archived +0 -456
- data/data/gemfile/v1.4.18/Gemfile +0 -3
- data/data/gemfile/v1.4.18/Gemfile.lock.archived +0 -486
- data/data/gemfile/v1.4.3/Gemfile +0 -3
- data/data/gemfile/v1.4.3/Gemfile.lock.archived +0 -339
- data/data/gemfile/v1.4.4/Gemfile +0 -3
- data/data/gemfile/v1.4.4/Gemfile.lock.archived +0 -339
- data/data/gemfile/v1.4.5/Gemfile +0 -3
- data/data/gemfile/v1.4.5/Gemfile.lock.archived +0 -348
- data/data/gemfile/v1.4.6/Gemfile +0 -3
- data/data/gemfile/v1.4.6/Gemfile.lock.archived +0 -357
- data/data/gemfile/v1.4.7/Gemfile +0 -3
- data/data/gemfile/v1.4.7/Gemfile.lock.archived +0 -391
- data/data/gemfile/v1.4.8/Gemfile +0 -3
- data/data/gemfile/v1.4.8/Gemfile.lock.archived +0 -445
- data/data/gemfile/v1.4.9/Gemfile +0 -3
- data/data/gemfile/v1.4.9/Gemfile.lock.archived +0 -448
- data/data/gemfile/v1.5.0/Gemfile +0 -3
- data/data/gemfile/v1.5.0/Gemfile.lock.archived +0 -478
- data/data/gemfile/v1.5.10/Gemfile +0 -3
- data/data/gemfile/v1.5.10/Gemfile.lock.archived +0 -668
- data/data/gemfile/v1.5.11/Gemfile +0 -3
- data/data/gemfile/v1.5.11/Gemfile.lock.archived +0 -668
- data/data/gemfile/v1.5.15/Gemfile +0 -3
- data/data/gemfile/v1.5.15/Gemfile.lock.archived +0 -686
- data/data/gemfile/v1.5.16/Gemfile +0 -3
- data/data/gemfile/v1.5.16/Gemfile.lock.archived +0 -684
- data/data/gemfile/v1.5.17/Gemfile +0 -3
- data/data/gemfile/v1.5.17/Gemfile.lock.archived +0 -684
- data/data/gemfile/v1.5.18/Gemfile +0 -5
- data/data/gemfile/v1.5.18/Gemfile.lock.archived +0 -691
- data/data/gemfile/v1.5.19/Gemfile +0 -5
- data/data/gemfile/v1.5.19/Gemfile.lock.archived +0 -703
- data/data/gemfile/v1.5.20/Gemfile +0 -5
- data/data/gemfile/v1.5.20/Gemfile.lock.archived +0 -703
- data/data/gemfile/v1.5.21/Gemfile +0 -5
- data/data/gemfile/v1.5.21/Gemfile.lock.archived +0 -707
- data/data/gemfile/v1.5.22/Gemfile +0 -5
- data/data/gemfile/v1.5.22/Gemfile.lock.archived +0 -707
- data/data/gemfile/v1.5.23/Gemfile +0 -5
- data/data/gemfile/v1.5.23/Gemfile.lock.archived +0 -711
- data/data/gemfile/v1.5.24/Gemfile +0 -5
- data/data/gemfile/v1.5.24/Gemfile.lock.archived +0 -711
- data/data/gemfile/v1.5.3/Gemfile +0 -3
- data/data/gemfile/v1.5.3/Gemfile.lock.archived +0 -651
- data/data/gemfile/v1.5.4/Gemfile +0 -3
- data/data/gemfile/v1.5.4/Gemfile.lock.archived +0 -657
- data/data/gemfile/v1.5.5/Gemfile +0 -3
- data/data/gemfile/v1.5.5/Gemfile.lock.archived +0 -657
- data/data/gemfile/v1.5.6/Gemfile +0 -3
- data/data/gemfile/v1.5.6/Gemfile.lock.archived +0 -657
- data/data/gemfile/v1.5.7/Gemfile +0 -3
- data/data/gemfile/v1.5.7/Gemfile.lock.archived +0 -657
- data/data/gemfile/v1.5.8/Gemfile +0 -3
- data/data/gemfile/v1.5.8/Gemfile.lock.archived +0 -655
- data/data/gemfile/v1.5.9/Gemfile +0 -3
- data/data/gemfile/v1.5.9/Gemfile.lock.archived +0 -656
- data/data/gemfile/v1.6.1/Gemfile +0 -5
- data/data/gemfile/v1.6.1/Gemfile.lock.archived +0 -721
- data/data/gemfile/v1.6.10/Gemfile +0 -5
- data/data/gemfile/v1.6.10/Gemfile.lock.archived +0 -744
- data/data/gemfile/v1.6.11/Gemfile +0 -5
- data/data/gemfile/v1.6.11/Gemfile.lock.archived +0 -744
- data/data/gemfile/v1.6.12/Gemfile +0 -5
- data/data/gemfile/v1.6.12/Gemfile.lock.archived +0 -745
- data/data/gemfile/v1.6.13/Gemfile +0 -5
- data/data/gemfile/v1.6.13/Gemfile.lock.archived +0 -745
- data/data/gemfile/v1.6.14/Gemfile +0 -5
- data/data/gemfile/v1.6.14/Gemfile.lock.archived +0 -754
- data/data/gemfile/v1.6.15/Gemfile +0 -5
- data/data/gemfile/v1.6.15/Gemfile.lock.archived +0 -757
- data/data/gemfile/v1.6.2/Gemfile +0 -5
- data/data/gemfile/v1.6.2/Gemfile.lock.archived +0 -718
- data/data/gemfile/v1.6.3/Gemfile +0 -5
- data/data/gemfile/v1.6.3/Gemfile.lock.archived +0 -728
- data/data/gemfile/v1.6.4/Gemfile +0 -5
- data/data/gemfile/v1.6.4/Gemfile.lock.archived +0 -730
- data/data/gemfile/v1.6.5/Gemfile +0 -5
- data/data/gemfile/v1.6.5/Gemfile.lock.archived +0 -733
- data/data/gemfile/v1.6.6/Gemfile +0 -5
- data/data/gemfile/v1.6.6/Gemfile.lock.archived +0 -733
- data/data/gemfile/v1.6.7/Gemfile +0 -5
- data/data/gemfile/v1.6.7/Gemfile.lock.archived +0 -733
- data/data/gemfile/v1.6.9/Gemfile +0 -5
- data/data/gemfile/v1.6.9/Gemfile.lock.archived +0 -744
- data/data/gemfile/v1.7.0/Gemfile +0 -5
- data/data/gemfile/v1.7.0/Gemfile.lock.archived +0 -750
- data/data/gemfile/v1.7.1/Gemfile +0 -5
- data/data/gemfile/v1.7.1/Gemfile.lock.archived +0 -750
- data/data/gemfile/v1.7.2/Gemfile +0 -5
- data/data/gemfile/v1.7.2/Gemfile.lock.archived +0 -747
- data/data/gemfile/v1.7.3/Gemfile +0 -5
- data/data/gemfile/v1.7.3/Gemfile.lock.archived +0 -755
- data/data/gemfile/v1.7.4/Gemfile +0 -5
- data/data/gemfile/v1.7.4/Gemfile.lock.archived +0 -756
- data/data/gemfile/v1.7.5/Gemfile +0 -5
- data/data/gemfile/v1.7.5/Gemfile.lock.archived +0 -759
- data/data/gemfile/v1.7.6/Gemfile +0 -5
- data/data/gemfile/v1.7.6/Gemfile.lock.archived +0 -768
- data/data/gemfile/v1.8.10/Gemfile +0 -5
- data/data/gemfile/v1.8.10/Gemfile.lock.archived +0 -792
- data/data/gemfile/v1.8.11/Gemfile +0 -5
- data/data/gemfile/v1.8.11/Gemfile.lock.archived +0 -862
- data/data/gemfile/v1.8.3/Gemfile +0 -5
- data/data/gemfile/v1.8.3/Gemfile.lock.archived +0 -773
- data/data/gemfile/v1.8.4/Gemfile +0 -5
- data/data/gemfile/v1.8.4/Gemfile.lock.archived +0 -768
- data/data/gemfile/v1.8.5/Gemfile +0 -5
- data/data/gemfile/v1.8.5/Gemfile.lock.archived +0 -768
- data/data/gemfile/v1.8.6/Gemfile +0 -5
- data/data/gemfile/v1.8.6/Gemfile.lock.archived +0 -777
- data/data/gemfile/v1.8.7/Gemfile +0 -5
- data/data/gemfile/v1.8.7/Gemfile.lock.archived +0 -777
- data/data/gemfile/v1.8.8/Gemfile +0 -5
- data/data/gemfile/v1.8.8/Gemfile.lock.archived +0 -778
- data/data/gemfile/v1.8.9/Gemfile +0 -5
- data/data/gemfile/v1.8.9/Gemfile.lock.archived +0 -775
- data/data/gemfile/v1.9.0/Gemfile +0 -5
- data/data/gemfile/v1.9.0/Gemfile.lock.archived +0 -871
- data/data/gemfile/v1.9.1/Gemfile +0 -5
- data/data/gemfile/v1.9.1/Gemfile.lock.archived +0 -906
- data/data/gemfile/v1.9.2/Gemfile +0 -5
- data/data/gemfile/v1.9.2/Gemfile.lock.archived +0 -898
- data/data/gemfile/v1.9.3/Gemfile +0 -5
- data/data/gemfile/v1.9.3/Gemfile.lock.archived +0 -898
- data/data/gemfile/v1.9.4/Gemfile +0 -5
- data/data/gemfile/v1.9.4/Gemfile.lock.archived +0 -901
- data/data/gemfile/v1.9.5/Gemfile +0 -5
- data/data/gemfile/v1.9.5/Gemfile.lock.archived +0 -903
- data/data/gemfile/v1.9.6/Gemfile +0 -5
- data/data/gemfile/v1.9.6/Gemfile.lock.archived +0 -900
- data/data/gemfile/v1.9.7/Gemfile +0 -5
- data/data/gemfile/v1.9.7/Gemfile.lock.archived +0 -922
- data/data/gemfile/v1.9.8/Gemfile +0 -5
- data/data/gemfile/v1.9.8/Gemfile.lock.archived +0 -933
- data/data/gemfile/versions.yaml +0 -751
- data/data/homebrew/versions.yaml +0 -567
- data/data/snap/github_tags.json +0 -42
- data/data/snap/versions.yaml +0 -589
- data/snapcraft-list-copied-from-site.md +0 -101
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
|
|
5
|
+
module Mnenv
|
|
6
|
+
module Shells
|
|
7
|
+
# PowerShell shell implementation (Windows)
|
|
8
|
+
class PowerShellShell < BaseShell
|
|
9
|
+
def name
|
|
10
|
+
'powershell'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def shim_extension
|
|
14
|
+
'.ps1'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def shim_content(executable_name)
|
|
18
|
+
<<~SHIM
|
|
19
|
+
# mnenv shim for PowerShell
|
|
20
|
+
$ErrorActionPreference = "Stop"
|
|
21
|
+
|
|
22
|
+
$MNENV_ROOT = if ($env:MNENV_ROOT) { $env:MNENV_ROOT } else { "$env:USERPROFILE\\.mnenv" }
|
|
23
|
+
|
|
24
|
+
# Resolve version and source using mnenv resolver
|
|
25
|
+
$versionFile = "$MNENV_ROOT\\version"
|
|
26
|
+
$sourceFile = "$MNENV_ROOT\\source"
|
|
27
|
+
|
|
28
|
+
# Check environment variables first
|
|
29
|
+
$VERSION = $env:METANORMA_VERSION
|
|
30
|
+
$SOURCE = $env:METANORMA_SOURCE
|
|
31
|
+
|
|
32
|
+
# Check local .metanorma-version file
|
|
33
|
+
if (-not $VERSION) {
|
|
34
|
+
$dir = (Get-Location).Path
|
|
35
|
+
$root = [System.IO.Path]::GetPathRoot($dir)
|
|
36
|
+
while ($dir -and $dir -ne $root) {
|
|
37
|
+
$localVersionFile = Join-Path $dir ".metanorma-version"
|
|
38
|
+
if (Test-Path $localVersionFile) {
|
|
39
|
+
$VERSION = Get-Content $localVersionFile -Raw
|
|
40
|
+
$VERSION = $VERSION.Trim()
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
$localSourceFile = Join-Path $dir ".metanorma-source"
|
|
44
|
+
if (-not $SOURCE -and (Test-Path $localSourceFile)) {
|
|
45
|
+
$SOURCE = Get-Content $localSourceFile -Raw
|
|
46
|
+
$SOURCE = $SOURCE.Trim()
|
|
47
|
+
}
|
|
48
|
+
$dir = Split-Path $dir -Parent
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Check global version file
|
|
53
|
+
if (-not $VERSION -and (Test-Path $versionFile)) {
|
|
54
|
+
$VERSION = Get-Content $versionFile -Raw
|
|
55
|
+
$VERSION = $VERSION.Trim()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (-not $SOURCE -and (Test-Path $sourceFile)) {
|
|
59
|
+
$SOURCE = Get-Content $sourceFile -Raw
|
|
60
|
+
$SOURCE = $SOURCE.Trim()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Default source
|
|
64
|
+
if (-not $SOURCE) {
|
|
65
|
+
$SOURCE = "gemfile"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (-not $VERSION) {
|
|
69
|
+
Write-Error "mnenv: version not set or invalid"
|
|
70
|
+
Write-Error "Set a version with: mnenv global <version> or mnenv local <version>"
|
|
71
|
+
exit 1
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Determine executable path based on source
|
|
75
|
+
# Installed versions are in $MNENV_ROOT\\installed\\<version>-<source>\\
|
|
76
|
+
if ($SOURCE -eq "binary") {
|
|
77
|
+
$EXECUTABLE = "$MNENV_ROOT\\installed\\$VERSION-$SOURCE\\metanorma.exe"
|
|
78
|
+
} else {
|
|
79
|
+
# Bundler creates .cmd files on Windows, not .bat
|
|
80
|
+
$EXECUTABLE = "$MNENV_ROOT\\installed\\$VERSION-$SOURCE\\bin\\#{executable_name}.cmd"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (-not (Test-Path $EXECUTABLE)) {
|
|
84
|
+
Write-Error "mnenv: #{executable_name} not installed for version $VERSION (source: $SOURCE)"
|
|
85
|
+
Write-Error "Install it with: mnenv install $VERSION --source $SOURCE"
|
|
86
|
+
exit 1
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
& $EXECUTABLE $args
|
|
90
|
+
SHIM
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def use_output(version, source)
|
|
94
|
+
lines = []
|
|
95
|
+
lines << "$env:METANORMA_VERSION = '#{version}'"
|
|
96
|
+
lines << "$env:METANORMA_SOURCE = '#{source}'" if source
|
|
97
|
+
lines << '# Run this in your PowerShell session'
|
|
98
|
+
lines.join("\n")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def config_file
|
|
102
|
+
File.expand_path('~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def windows?
|
|
106
|
+
true
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'set'
|
|
4
|
+
require_relative 'shells/factory'
|
|
5
|
+
|
|
6
|
+
module Mnenv
|
|
7
|
+
class ShimManager
|
|
8
|
+
RESOLVER_SCRIPT = File.expand_path('resolver', __dir__).freeze
|
|
9
|
+
|
|
10
|
+
attr_reader :shims_dir, :installed_dir
|
|
11
|
+
|
|
12
|
+
def initialize(shims_dir: nil, installed_dir: nil)
|
|
13
|
+
@shims_dir = shims_dir || Paths::SHIMS_DIR
|
|
14
|
+
@installed_dir = installed_dir || Paths::INSTALLED_DIR
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def regenerate_all
|
|
18
|
+
FileUtils.mkdir_p(@shims_dir)
|
|
19
|
+
FileUtils.mkdir_p(Paths::LIB_DIR)
|
|
20
|
+
|
|
21
|
+
# Copy resolver script to mnenv lib directory (for Unix shells)
|
|
22
|
+
if File.exist?(RESOLVER_SCRIPT)
|
|
23
|
+
FileUtils.cp(RESOLVER_SCRIPT, File.join(Paths::LIB_DIR, 'resolver'))
|
|
24
|
+
File.chmod(0o755, File.join(Paths::LIB_DIR, 'resolver'))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
executables = discover_executables
|
|
28
|
+
|
|
29
|
+
executables.each do |exe|
|
|
30
|
+
create_shims(exe)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
remove_obsolete_shims(executables)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create_shims(executable_name)
|
|
37
|
+
# Create shims for all platform-appropriate shells
|
|
38
|
+
Shells::ShellFactory.platform_shells.each do |shell|
|
|
39
|
+
create_shim_for_shell(executable_name, shell)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def create_shim_for_shell(executable_name, shell)
|
|
46
|
+
# For bash, no extension; for PowerShell, .ps1; for CMD, .bat
|
|
47
|
+
extension = shell.shim_extension
|
|
48
|
+
shim_name = executable_name + extension
|
|
49
|
+
shim_path = File.join(@shims_dir, shim_name)
|
|
50
|
+
|
|
51
|
+
File.write(shim_path, shell.shim_content(executable_name))
|
|
52
|
+
File.chmod(0o755, shim_path) unless shell.windows?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def discover_executables
|
|
56
|
+
executables = Set.new
|
|
57
|
+
|
|
58
|
+
# Scan installed directories with new naming convention: <version>-<source>
|
|
59
|
+
Dir.glob(File.join(@installed_dir, '*')).each do |version_dir|
|
|
60
|
+
next unless File.directory?(version_dir)
|
|
61
|
+
|
|
62
|
+
dir_name = File.basename(version_dir)
|
|
63
|
+
version, source = Paths.parse_version_dir(dir_name)
|
|
64
|
+
next unless version && source
|
|
65
|
+
|
|
66
|
+
case source
|
|
67
|
+
when 'gemfile'
|
|
68
|
+
# Discover binstubs from bundle install
|
|
69
|
+
bin_dir = File.join(version_dir, 'bin')
|
|
70
|
+
next unless Dir.exist?(bin_dir)
|
|
71
|
+
|
|
72
|
+
Dir.glob(File.join(bin_dir, '*')).each do |bin_path|
|
|
73
|
+
next if File.directory?(bin_path)
|
|
74
|
+
|
|
75
|
+
basename = File.basename(bin_path)
|
|
76
|
+
|
|
77
|
+
# On Windows, bundler creates both 'command' and 'command.cmd'
|
|
78
|
+
# Skip .cmd and .bat files - we'll create shims from the base name
|
|
79
|
+
next if windows? && (basename.end_with?('.cmd') || basename.end_with?('.bat'))
|
|
80
|
+
|
|
81
|
+
executables << basename if windows? || File.executable?(bin_path)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
when 'binary'
|
|
85
|
+
# Binary installations have a single metanorma binary
|
|
86
|
+
binary_path = File.join(version_dir, 'metanorma')
|
|
87
|
+
exe_path = File.join(version_dir, 'metanorma.exe')
|
|
88
|
+
|
|
89
|
+
if File.exist?(binary_path) && (File.executable?(binary_path) || windows?)
|
|
90
|
+
executables << 'metanorma'
|
|
91
|
+
elsif File.exist?(exe_path)
|
|
92
|
+
executables << 'metanorma'
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
executables.to_a.sort
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def remove_obsolete_shims(valid_executables)
|
|
101
|
+
# Build list of valid shim names (with extensions)
|
|
102
|
+
valid_shim_names = Set.new
|
|
103
|
+
Shells::ShellFactory.platform_shells.each do |shell|
|
|
104
|
+
valid_executables.each do |exe|
|
|
105
|
+
valid_shim_names << exe + shell.shim_extension
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
Dir.glob(File.join(@shims_dir, '*')).each do |shim_path|
|
|
110
|
+
next if File.directory?(shim_path)
|
|
111
|
+
|
|
112
|
+
shim_name = File.basename(shim_path)
|
|
113
|
+
File.delete(shim_path) unless valid_shim_names.include?(shim_name)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def windows?
|
|
118
|
+
RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
data/lib/mnenv/snap.rb
ADDED
|
@@ -8,16 +8,10 @@ module Mnenv
|
|
|
8
8
|
def version_class = SnapVersion
|
|
9
9
|
def source_name = :snap
|
|
10
10
|
|
|
11
|
-
# Override
|
|
11
|
+
# Override cache_version to use composite key for Snap
|
|
12
12
|
# Since same version can have multiple revisions/arch/channels
|
|
13
|
-
def
|
|
13
|
+
def cache_version(version)
|
|
14
14
|
@versions_cache[snap_key(version)] = version
|
|
15
|
-
persist
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def save_all(versions)
|
|
19
|
-
versions.each { |v| @versions_cache[snap_key(v)] = v }
|
|
20
|
-
persist
|
|
21
15
|
end
|
|
22
16
|
|
|
23
17
|
# Override find to work with composite keys
|
|
@@ -55,16 +49,5 @@ module Mnenv
|
|
|
55
49
|
raise ArgumentError, 'snap_key requires 1 or 4 arguments'
|
|
56
50
|
end
|
|
57
51
|
end
|
|
58
|
-
|
|
59
|
-
# Override load to handle snap composite keys
|
|
60
|
-
def load
|
|
61
|
-
data = YAML.load_file(versions_file_path)
|
|
62
|
-
return if data.nil? || data['versions'].nil?
|
|
63
|
-
|
|
64
|
-
data['versions'].each do |version_hash|
|
|
65
|
-
version = version_class.new(version_hash)
|
|
66
|
-
@versions_cache[snap_key(version)] = version
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
52
|
end
|
|
70
53
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mnenv
|
|
4
|
+
# Registry for version sources (gemfile, binary, snap, homebrew, chocolatey)
|
|
5
|
+
# Enables plugin architecture - new sources just need to register themselves
|
|
6
|
+
class SourceRegistry
|
|
7
|
+
class DuplicateSourceError < StandardError; end
|
|
8
|
+
class UnknownSourceError < StandardError; end
|
|
9
|
+
|
|
10
|
+
# Register a new source
|
|
11
|
+
# @param name [String] the source identifier (e.g., 'gemfile', 'binary')
|
|
12
|
+
# @param repository [Class] the repository class for this source
|
|
13
|
+
# @param model [Class] the version model class for this source
|
|
14
|
+
# @param installer [Class, nil] the installer class (optional)
|
|
15
|
+
def self.register(name:, repository:, model:, installer: nil)
|
|
16
|
+
name = name.to_s
|
|
17
|
+
raise DuplicateSourceError, "Source '#{name}' is already registered" if sources.key?(name)
|
|
18
|
+
|
|
19
|
+
sources[name] = {
|
|
20
|
+
repository: repository,
|
|
21
|
+
model: model,
|
|
22
|
+
installer: installer
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Get repository class for a source
|
|
27
|
+
def self.repository(name)
|
|
28
|
+
source = sources[name.to_s]
|
|
29
|
+
raise UnknownSourceError, "Unknown source: #{name}" unless source
|
|
30
|
+
|
|
31
|
+
source[:repository]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Get model class for a source
|
|
35
|
+
def self.model(name)
|
|
36
|
+
source = sources[name.to_s]
|
|
37
|
+
raise UnknownSourceError, "Unknown source: #{name}" unless source
|
|
38
|
+
|
|
39
|
+
source[:model]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get installer class for a source
|
|
43
|
+
def self.installer(name)
|
|
44
|
+
source = sources[name.to_s]
|
|
45
|
+
raise UnknownSourceError, "Unknown source: #{name}" unless source
|
|
46
|
+
|
|
47
|
+
source[:installer]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get all registered source names
|
|
51
|
+
def self.all_names
|
|
52
|
+
sources.keys.sort
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Check if a source is registered
|
|
56
|
+
def self.registered?(name)
|
|
57
|
+
sources.key?(name.to_s)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Clear all registrations (useful for testing)
|
|
61
|
+
def self.clear
|
|
62
|
+
@sources = nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.sources
|
|
66
|
+
@sources ||= {}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'source_registry'
|
|
4
|
+
require_relative 'gemfile_repository'
|
|
5
|
+
require_relative 'binary_repository'
|
|
6
|
+
require_relative 'models/gemfile_version'
|
|
7
|
+
require_relative 'models/binary_version'
|
|
8
|
+
require_relative 'installers/gemfile_installer'
|
|
9
|
+
require_relative 'installers/binary_installer'
|
|
10
|
+
|
|
11
|
+
module Mnenv
|
|
12
|
+
# Auto-registration of built-in sources
|
|
13
|
+
# This enables the plugin architecture - new sources just need to register themselves
|
|
14
|
+
module Sources
|
|
15
|
+
class << self
|
|
16
|
+
# Register all built-in sources
|
|
17
|
+
def setup
|
|
18
|
+
register_gemfile
|
|
19
|
+
register_binary
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def register_gemfile
|
|
25
|
+
SourceRegistry.register(
|
|
26
|
+
name: 'gemfile',
|
|
27
|
+
repository: GemfileRepository,
|
|
28
|
+
model: GemfileVersion,
|
|
29
|
+
installer: Installers::GemfileInstaller
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def register_binary
|
|
34
|
+
SourceRegistry.register(
|
|
35
|
+
name: 'binary',
|
|
36
|
+
repository: BinaryRepository,
|
|
37
|
+
model: BinaryVersion,
|
|
38
|
+
installer: Installers::BinaryInstaller
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Auto-setup on load
|
|
46
|
+
Mnenv::Sources.setup
|
data/lib/mnenv/version.rb
CHANGED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mnenv
|
|
4
|
+
# Centralized version and source resolution with clear precedence:
|
|
5
|
+
# 1. Environment variables (METANORMA_VERSION, METANORMA_SOURCE)
|
|
6
|
+
# 2. Local files (.metanorma-version, .metanorma-source) - walk up tree
|
|
7
|
+
# 3. Global files (~/.mnenv/version, ~/.mnenv/source)
|
|
8
|
+
# 4. Defaults (gemfile for source)
|
|
9
|
+
#
|
|
10
|
+
# This class is the single source of truth for version resolution.
|
|
11
|
+
# The Bash resolver (lib/mnenv/resolver) is kept for shims only.
|
|
12
|
+
class VersionResolver
|
|
13
|
+
# Resolve the current Metanorma version
|
|
14
|
+
# @return [String, nil] The resolved version or nil if not set
|
|
15
|
+
def resolve_version
|
|
16
|
+
from_env('METANORMA_VERSION') ||
|
|
17
|
+
from_local_file('.metanorma-version') ||
|
|
18
|
+
from_global_file(Paths::VERSION_FILE)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Resolve the current Metanorma source
|
|
22
|
+
# @return [String] The resolved source (defaults to 'gemfile')
|
|
23
|
+
def resolve_source
|
|
24
|
+
from_env('METANORMA_SOURCE') ||
|
|
25
|
+
from_local_file('.metanorma-source') ||
|
|
26
|
+
from_global_file(Paths::SOURCE_FILE) ||
|
|
27
|
+
'gemfile'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Resolve both version and source
|
|
31
|
+
# @return [Array<String, String>] Tuple of [version, source]
|
|
32
|
+
def resolve
|
|
33
|
+
[resolve_version, resolve_source]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Check if a version is set anywhere
|
|
37
|
+
# @return [Boolean]
|
|
38
|
+
def version_set?
|
|
39
|
+
!resolve_version.nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Check if a source is explicitly set (not default)
|
|
43
|
+
# @return [Boolean]
|
|
44
|
+
def source_set?
|
|
45
|
+
from_env('METANORMA_SOURCE') ||
|
|
46
|
+
from_local_file('.metanorma-source') ||
|
|
47
|
+
from_global_file(Paths::SOURCE_FILE)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get the source of version resolution (for debugging)
|
|
51
|
+
# @return [Symbol] :environment, :local, :global, or :none
|
|
52
|
+
def version_source
|
|
53
|
+
return :environment if from_env('METANORMA_VERSION')
|
|
54
|
+
return :local if from_local_file('.metanorma-version')
|
|
55
|
+
return :global if from_global_file(Paths::VERSION_FILE)
|
|
56
|
+
|
|
57
|
+
:none
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Get the source of source resolution (for debugging)
|
|
61
|
+
# @return [Symbol] :environment, :local, :global, or :default
|
|
62
|
+
def source_source
|
|
63
|
+
return :environment if from_env('METANORMA_SOURCE')
|
|
64
|
+
return :local if from_local_file('.metanorma-source')
|
|
65
|
+
return :global if from_global_file(Paths::SOURCE_FILE)
|
|
66
|
+
|
|
67
|
+
:default
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Read from environment variable
|
|
73
|
+
# @param var [String] Environment variable name
|
|
74
|
+
# @return [String, nil] Value or nil if not set/empty
|
|
75
|
+
def from_env(var)
|
|
76
|
+
value = ENV[var]
|
|
77
|
+
value&.strip&.then { |v| v unless v.empty? }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Read from local file, walking up directory tree
|
|
81
|
+
# @param filename [String] Filename to look for
|
|
82
|
+
# @return [String, nil] File contents or nil if not found
|
|
83
|
+
def from_local_file(filename)
|
|
84
|
+
dir = Dir.pwd
|
|
85
|
+
|
|
86
|
+
loop do
|
|
87
|
+
path = File.join(dir, filename)
|
|
88
|
+
return File.read(path).strip if File.exist?(path)
|
|
89
|
+
|
|
90
|
+
parent = File.dirname(dir)
|
|
91
|
+
break if parent == dir # Reached root
|
|
92
|
+
|
|
93
|
+
dir = parent
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Read from global file
|
|
100
|
+
# @param path [String] Full path to file
|
|
101
|
+
# @return [String, nil] File contents or nil if not found
|
|
102
|
+
def from_global_file(path)
|
|
103
|
+
File.read(path).strip if File.exist?(path)
|
|
104
|
+
rescue StandardError
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'git'
|
|
5
|
+
|
|
6
|
+
module Mnenv
|
|
7
|
+
# Manages the local clone of the metanorma/versions repository
|
|
8
|
+
# Similar to how Homebrew manages its core tap
|
|
9
|
+
class VersionsManager
|
|
10
|
+
VERSIONS_REPO = 'https://github.com/metanorma/versions.git'
|
|
11
|
+
DEFAULT_MNENV_DIR = File.expand_path('~/.mnenv')
|
|
12
|
+
VERSIONS_DIR = 'versions'
|
|
13
|
+
|
|
14
|
+
attr_reader :mnenv_dir, :versions_path
|
|
15
|
+
|
|
16
|
+
def initialize(mnenv_dir: nil)
|
|
17
|
+
@mnenv_dir = mnenv_dir || DEFAULT_MNENV_DIR
|
|
18
|
+
@versions_path = File.join(@mnenv_dir, VERSIONS_DIR)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Ensure versions repository is cloned and up to date
|
|
22
|
+
# @param update [Boolean] Force update (git fetch) even if already cloned
|
|
23
|
+
# @return [String] Path to the versions data directory
|
|
24
|
+
def ensure_versions_data(update: false)
|
|
25
|
+
if cloned?
|
|
26
|
+
update_clone if update || stale?
|
|
27
|
+
else
|
|
28
|
+
clone_repo
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
data_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Check if versions repository is cloned
|
|
35
|
+
def cloned?
|
|
36
|
+
File.directory?(File.join(versions_path, '.git'))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Check if the clone is stale (older than 24 hours)
|
|
40
|
+
def stale?
|
|
41
|
+
return true unless cloned?
|
|
42
|
+
|
|
43
|
+
last_update_file = File.join(versions_path, '.mnenv_last_update')
|
|
44
|
+
return true unless File.exist?(last_update_file)
|
|
45
|
+
|
|
46
|
+
last_update = File.mtime(last_update_file)
|
|
47
|
+
Time.now - last_update > 86_400 # 24 hours
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Path to the data directory within the versions repository
|
|
51
|
+
def data_path
|
|
52
|
+
File.join(versions_path, 'data')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Clone the versions repository using the git gem
|
|
56
|
+
def clone_repo
|
|
57
|
+
FileUtils.mkdir_p(mnenv_dir)
|
|
58
|
+
Git.clone(VERSIONS_REPO, VERSIONS_DIR, path: mnenv_dir, depth: 1)
|
|
59
|
+
touch_update_marker
|
|
60
|
+
rescue Git::GitExecuteError => e
|
|
61
|
+
raise "Failed to clone versions repository: #{e.message}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Update the versions repository using the git gem
|
|
65
|
+
def update_clone
|
|
66
|
+
return unless cloned?
|
|
67
|
+
|
|
68
|
+
g = Git.open(versions_path)
|
|
69
|
+
g.fetch
|
|
70
|
+
g.reset_hard('origin/main')
|
|
71
|
+
touch_update_marker
|
|
72
|
+
rescue Git::GitExecuteError => e
|
|
73
|
+
warn "Warning: Failed to update versions repository: #{e.message}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Force update the versions repository
|
|
77
|
+
def update
|
|
78
|
+
if cloned?
|
|
79
|
+
update_clone
|
|
80
|
+
else
|
|
81
|
+
clone_repo
|
|
82
|
+
end
|
|
83
|
+
data_path
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def touch_update_marker
|
|
89
|
+
FileUtils.touch(File.join(versions_path, '.mnenv_last_update'))
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
data/lib/mnenv.rb
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
require 'lutaml/model'
|
|
4
4
|
require 'thor'
|
|
5
5
|
|
|
6
|
+
require_relative 'mnenv/paths'
|
|
7
|
+
require_relative 'mnenv/platform_detector'
|
|
8
|
+
require_relative 'mnenv/version_resolver'
|
|
6
9
|
require_relative 'mnenv/models'
|
|
10
|
+
require_relative 'mnenv/source_registry'
|
|
11
|
+
require_relative 'mnenv/sources'
|
|
7
12
|
require_relative 'mnenv/commands'
|
|
13
|
+
require_relative 'mnenv/installer'
|
|
8
14
|
require_relative 'mnenv/cli'
|
data/mnenv.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.description = 'Unified interface for discovering and managing Metanorma ' \
|
|
13
13
|
'versions from Gemfile (Docker), Snap, Homebrew, and Chocolatey sources. ' \
|
|
14
14
|
'Provides mnenv CLI command for querying version information.'
|
|
15
|
-
spec.homepage = 'https://github.com/metanorma/
|
|
15
|
+
spec.homepage = 'https://github.com/metanorma/mnenv'
|
|
16
16
|
spec.license = 'MIT'
|
|
17
17
|
|
|
18
18
|
spec.required_ruby_version = '>= 3.1'
|
|
@@ -34,10 +34,13 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
|
|
35
35
|
# Runtime dependencies
|
|
36
36
|
spec.add_dependency 'activesupport'
|
|
37
|
+
spec.add_dependency 'git'
|
|
37
38
|
spec.add_dependency 'lutaml-model', '~> 0.7'
|
|
38
39
|
spec.add_dependency 'lutaml-xsd', '~> 1.0'
|
|
39
40
|
spec.add_dependency 'moxml'
|
|
40
41
|
spec.add_dependency 'nokogiri'
|
|
42
|
+
spec.add_dependency 'octokit'
|
|
41
43
|
spec.add_dependency 'paint'
|
|
42
44
|
spec.add_dependency 'thor', '~> 1.0'
|
|
45
|
+
spec.add_dependency 'tty-prompt'
|
|
43
46
|
end
|