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.
- 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 +42 -0
- data/lib/mnenv/commands/version_command.rb +213 -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 +17 -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/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/version.rb +1 -1
- data/lib/mnenv/versions_manager.rb +92 -0
- data/lib/mnenv.rb +3 -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 +82 -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,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
|
data/lib/mnenv/version.rb
CHANGED
|
@@ -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
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
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Local cross-source switching test script for mnenv
|
|
3
|
+
# Tests switching between gemfile and binary for the same version
|
|
4
|
+
# Usage: ./scripts/cross-source-switching-test.sh [VERSION]
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colors
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
log_info() {
|
|
16
|
+
echo -e "${GREEN}[INFO]${NC} $1"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
log_warn() {
|
|
20
|
+
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
log_error() {
|
|
24
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
log_step() {
|
|
28
|
+
echo -e "${BLUE}=== $1 ===${NC}"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Version to test
|
|
32
|
+
VERSION="${1:-1.14.3}"
|
|
33
|
+
|
|
34
|
+
# Check if we're in the mnenv directory
|
|
35
|
+
if [ ! -f "mnenv.gemspec" ]; then
|
|
36
|
+
log_error "Please run this script from the mnenv root directory"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Install mnenv
|
|
41
|
+
log_step "Installing mnenv"
|
|
42
|
+
bundle install > /dev/null 2>&1
|
|
43
|
+
rake install > /dev/null 2>&1
|
|
44
|
+
log_info "mnenv $(mnenv version) installed"
|
|
45
|
+
|
|
46
|
+
# Add mnenv to PATH
|
|
47
|
+
export PATH="$HOME/.mnenv/shims:$PATH"
|
|
48
|
+
|
|
49
|
+
# Clean up any existing test state
|
|
50
|
+
log_step "Cleaning up previous test state"
|
|
51
|
+
rm -f ~/.mnenv/version ~/.mnenv/source
|
|
52
|
+
rm -rf "/tmp/mnenv-cross-test-$VERSION"
|
|
53
|
+
mkdir -p "/tmp/mnenv-cross-test-$VERSION"
|
|
54
|
+
|
|
55
|
+
# Check binary availability
|
|
56
|
+
log_step "Checking binary availability for version $VERSION"
|
|
57
|
+
BINARY_URL="https://github.com/metanorma/packed-mn/releases/download/v${VERSION}/metanorma-$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
58
|
+
BINARY_AVAILABLE=false
|
|
59
|
+
|
|
60
|
+
if curl -s -f -L -o /dev/null "$BINARY_URL" 2>/dev/null; then
|
|
61
|
+
BINARY_AVAILABLE=true
|
|
62
|
+
log_info "Binary is available for $VERSION"
|
|
63
|
+
else
|
|
64
|
+
log_warn "Binary NOT available for $VERSION"
|
|
65
|
+
log_info "Will test gemfile installation only"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Install with gemfile
|
|
69
|
+
log_step "Installing Metanorma $VERSION (gemfile)"
|
|
70
|
+
if mnenv install "$VERSION" --source gemfile > /dev/null 2>&1; then
|
|
71
|
+
log_info "✓ Gemfile installation successful"
|
|
72
|
+
else
|
|
73
|
+
log_warn "⚠ Gemfile installation may have failed (may already be installed)"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Install with binary
|
|
77
|
+
if [ "$BINARY_AVAILABLE" = true ]; then
|
|
78
|
+
log_step "Installing Metanorma $VERSION (binary)"
|
|
79
|
+
if mnenv install "$VERSION" --source binary > /dev/null 2>&1; then
|
|
80
|
+
log_info "✓ Binary installation successful"
|
|
81
|
+
else
|
|
82
|
+
log_warn "⚠ Binary installation may have failed (may already be installed)"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Show both installations
|
|
86
|
+
log_step "Installation structure"
|
|
87
|
+
echo "Gemfile installation:"
|
|
88
|
+
ls -lah ~/.mnenv/versions/"$VERSION"/gemfile/ 2>/dev/null || echo " Not found"
|
|
89
|
+
|
|
90
|
+
echo ""
|
|
91
|
+
echo "Binary installation:"
|
|
92
|
+
ls -lah ~/.mnenv/versions/"$VERSION"/binary/ 2>/dev/null || echo " Not found"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Show installed versions
|
|
96
|
+
log_step "Installed versions"
|
|
97
|
+
mnenv versions
|
|
98
|
+
|
|
99
|
+
if [ "$BINARY_AVAILABLE" = false ]; then
|
|
100
|
+
echo ""
|
|
101
|
+
log_warn "Binary not available - skipping cross-source tests"
|
|
102
|
+
log_info "Binary tests require packed-mn releases"
|
|
103
|
+
exit 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Test 1: Switch from gemfile to binary
|
|
107
|
+
log_step "Test 1: Switch from gemfile to binary"
|
|
108
|
+
mnenv global "$VERSION" --source gemfile
|
|
109
|
+
v_gemfile=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
110
|
+
log_info "Gemfile source: metanorma --version = $v_gemfile"
|
|
111
|
+
|
|
112
|
+
mnenv global "$VERSION" --source binary
|
|
113
|
+
v_binary=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
114
|
+
log_info "Binary source: metanorma --version = $v_binary"
|
|
115
|
+
|
|
116
|
+
if [ "$v_gemfile" = "$VERSION" ] && [ "$v_binary" = "$VERSION" ]; then
|
|
117
|
+
log_info "✓ Both sources produce correct version $VERSION"
|
|
118
|
+
else
|
|
119
|
+
log_error "✗ Version mismatch: gemfile=$v_gemfile, binary=$v_binary"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Test 2: Switch from binary to gemfile
|
|
124
|
+
log_step "Test 2: Switch from binary to gemfile"
|
|
125
|
+
mnenv global "$VERSION" --source binary
|
|
126
|
+
v1=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
127
|
+
|
|
128
|
+
mnenv global "$VERSION" --source gemfile
|
|
129
|
+
v2=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
130
|
+
|
|
131
|
+
if [ "$v1" = "$VERSION" ] && [ "$v2" = "$VERSION" ]; then
|
|
132
|
+
log_info "✓ Bidirectional switching works"
|
|
133
|
+
else
|
|
134
|
+
log_error "✗ Version mismatch: binary=$v1, gemfile=$v2"
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Test 3: Rapid switching
|
|
139
|
+
log_step "Test 3: Rapid source switching (5 rounds)"
|
|
140
|
+
for i in {1..5}; do
|
|
141
|
+
mnenv global "$VERSION" --source gemfile > /dev/null
|
|
142
|
+
v_g=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
143
|
+
|
|
144
|
+
mnenv global "$VERSION" --source binary > /dev/null
|
|
145
|
+
v_b=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
146
|
+
|
|
147
|
+
if [ "$v_g" != "$VERSION" ] || [ "$v_b" != "$VERSION" ]; then
|
|
148
|
+
log_error "✗ Round $i failed: gemfile=$v_g, binary=$v_b"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
done
|
|
152
|
+
log_info "✓ Rapid switching test passed"
|
|
153
|
+
|
|
154
|
+
# Test 4: Local override with different source
|
|
155
|
+
log_step "Test 4: Local override with source change"
|
|
156
|
+
cd "/tmp/mnenv-cross-test-$VERSION"
|
|
157
|
+
|
|
158
|
+
# Set global to gemfile
|
|
159
|
+
mnenv global "$VERSION" --source gemfile > /dev/null
|
|
160
|
+
v_global=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
161
|
+
|
|
162
|
+
# Set local to binary
|
|
163
|
+
mnenv local "$VERSION" --source binary > /dev/null
|
|
164
|
+
v_local=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
165
|
+
|
|
166
|
+
if [ "$v_global" = "$VERSION" ] && [ "$v_local" = "$VERSION" ]; then
|
|
167
|
+
log_info "✓ Local override works with different source"
|
|
168
|
+
else
|
|
169
|
+
log_error "✗ Local override failed"
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Test 5: Shell override takes precedence
|
|
174
|
+
log_step "Test 5: Shell session override"
|
|
175
|
+
# Local is binary
|
|
176
|
+
export METANORMA_VERSION="$VERSION"
|
|
177
|
+
export METANORMA_SOURCE=gemfile
|
|
178
|
+
v_env=$(metanorma --version 2>&1 | grep -oP '\d+\.\d+\.\d+' || echo "failed")
|
|
179
|
+
|
|
180
|
+
if [ "$v_env" = "$VERSION" ]; then
|
|
181
|
+
log_info "✓ Environment variable overrides local file"
|
|
182
|
+
else
|
|
183
|
+
log_error "✗ Environment override failed"
|
|
184
|
+
exit 1
|
|
185
|
+
fi
|
|
186
|
+
unset METANORMA_VERSION METANORMA_SOURCE
|
|
187
|
+
|
|
188
|
+
# Test 6: Version list shows both sources
|
|
189
|
+
log_step "Test 6: Version list shows both sources"
|
|
190
|
+
if mnenv versions | grep -q "$VERSION.*gemfile"; then
|
|
191
|
+
log_info "✓ Gemfile source shown in version list"
|
|
192
|
+
else
|
|
193
|
+
log_error "✗ Gemfile source not in version list"
|
|
194
|
+
exit 1
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
if mnenv versions | grep -q "$VERSION.*binary"; then
|
|
198
|
+
log_info "✓ Binary source shown in version list"
|
|
199
|
+
else
|
|
200
|
+
log_error "✗ Binary source not in version list"
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# Final state
|
|
205
|
+
log_step "All tests passed!"
|
|
206
|
+
echo ""
|
|
207
|
+
echo "Final state:"
|
|
208
|
+
echo " Global version: $(cat ~/.mnenv/version 2>/dev/null || echo 'not set')"
|
|
209
|
+
echo " Global source: $(cat ~/.mnenv/source 2>/dev/null || echo 'not set')"
|
|
210
|
+
echo " Current metanorma: $(metanorma --version 2>&1 | head -1)"
|
|
211
|
+
|
|
212
|
+
# Clean up
|
|
213
|
+
cd /
|
|
214
|
+
rm -rf "/tmp/mnenv-cross-test-$VERSION"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Local integration test script for mnenv
|
|
3
|
+
# Usage: ./scripts/integration-test.sh [gemfile|binary]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Configuration
|
|
8
|
+
METANORMA_VERSION="${METANORMA_VERSION:-1.14.4}"
|
|
9
|
+
METHOD="${1:-gemfile}"
|
|
10
|
+
SAMPLES_REPO="${SAMPLES_REPO:-metanorma/mn-samples-cc}"
|
|
11
|
+
SAMPLES_DIR="/tmp/mn-samples-cc"
|
|
12
|
+
|
|
13
|
+
# Colors
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
GREEN='\033[0;32m'
|
|
16
|
+
YELLOW='\033[1;33m'
|
|
17
|
+
NC='\033[0m' # No Color
|
|
18
|
+
|
|
19
|
+
log_info() {
|
|
20
|
+
echo -e "${GREEN}[INFO]${NC} $1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
log_warn() {
|
|
24
|
+
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
log_error() {
|
|
28
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Check if we're in the mnenv directory
|
|
32
|
+
if [ ! -f "mnenv.gemspec" ]; then
|
|
33
|
+
log_error "Please run this script from the mnenv root directory"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Check if mnenv is installed
|
|
38
|
+
if ! command -v mnenv &> /dev/null; then
|
|
39
|
+
log_info "Installing mnenv..."
|
|
40
|
+
bundle install
|
|
41
|
+
rake install
|
|
42
|
+
else
|
|
43
|
+
log_info "mnenv is already installed"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Install Metanorma
|
|
47
|
+
log_info "Installing Metanorma ${METANORMA_VERSION} (method: ${METHOD})..."
|
|
48
|
+
mnenv install "${METANORMA_VERSION}" --source "${METHOD}"
|
|
49
|
+
mnenv global "${METANORMA_VERSION}" --source "${METHOD}"
|
|
50
|
+
|
|
51
|
+
# Show installed versions
|
|
52
|
+
log_info "Installed versions:"
|
|
53
|
+
mnenv versions
|
|
54
|
+
|
|
55
|
+
# Clone or update samples repository
|
|
56
|
+
if [ -d "$SAMPLES_DIR" ]; then
|
|
57
|
+
log_info "Updating samples repository..."
|
|
58
|
+
cd "$SAMPLES_DIR"
|
|
59
|
+
git pull
|
|
60
|
+
else
|
|
61
|
+
log_info "Cloning samples repository..."
|
|
62
|
+
git clone "https://github.com/${SAMPLES_REPO}.git" "$SAMPLES_DIR"
|
|
63
|
+
cd "$SAMPLES_DIR"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Test single document compilation
|
|
67
|
+
log_info "Testing single document compilation..."
|
|
68
|
+
if metanorma compile sources/cc-18011.adoc; then
|
|
69
|
+
log_info "Document compilation successful"
|
|
70
|
+
ls -lah sources/cc-18011.* 2>/dev/null || true
|
|
71
|
+
else
|
|
72
|
+
log_error "Document compilation failed"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Test site generation
|
|
77
|
+
log_info "Testing site generation..."
|
|
78
|
+
if metanorma site generate --agree-to-terms; then
|
|
79
|
+
log_info "Site generation successful"
|
|
80
|
+
if [ -d "site" ]; then
|
|
81
|
+
log_info "Site contents:"
|
|
82
|
+
ls -lah site/ | head -20
|
|
83
|
+
fi
|
|
84
|
+
else
|
|
85
|
+
log_error "Site generation failed"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
log_info "All tests passed!"
|