Skip to content

Commit

Permalink
Merge pull request #53 from maxfierke/mf-managed_mise_install
Browse files Browse the repository at this point in the history
Implement managed mise install
  • Loading branch information
maxfierke authored Jan 29, 2024
2 parents 2e056d0 + 49184e8 commit 7d4cf11
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Support for using [mise](https://mise.jdx.dev) to manage language runtime versions (#50). `config.hcl` can be configured as such to enable it:
- Support for using [mise](https://mise.jdx.dev) to manage language runtime versions (#50, #53). `config.hcl` can be configured as such to enable it:
```
version = "1.1"
Expand Down
5 changes: 5 additions & 0 deletions src/mstrap/platform.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ module MStrap
ENV["MSTRAP_IGNORE_GIT"]? != "true" && (`command -v git` && $?.success?)
end

# Indicates whether the host platform has GPG installed
def self.has_gpg?
!!(`command -v gpg` && $?.success?)
end

# Installs a list of packages using the platform's package manager
def self.install_packages!(packages : Array(String))
platform.install_packages!(packages)
Expand Down
1 change: 1 addition & 0 deletions src/mstrap/runtime_manager.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module MStrap
abstract def runtime_exec(language_name : String, command : String, args : Array(String)? = nil, runtime_version : String? = nil)
abstract def set_version(language_name : String, version : String?) : Bool
abstract def set_global_version(language_name : String, version : String) : Bool
abstract def shell_activation(shell_name : String) : String

macro finished
# :nodoc:
Expand Down
13 changes: 13 additions & 0 deletions src/mstrap/runtime_managers/asdf.cr
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ module MStrap
cmd "asdf global #{plugin_name(language_name)} #{version}", quiet: true
end

def shell_activation(shell_name : String) : String
<<-SHELL
# Activate asdf for language runtime version management
if [ -d "$(brew --prefix asdf)" ]; then
source "$(brew --prefix asdf)/libexec/asdf.sh"
if [ ! -f "$HOME/.asdfrc" ]; then
echo "legacy_version_file = yes\n" > "$HOME/.asdfrc"
fi
fi
SHELL
end

private def version_env_var(language_name) : String
if asdf_plugin_name = plugin_name(language_name)
"ASDF_#{asdf_plugin_name.upcase}_VERSION"
Expand Down
11 changes: 11 additions & 0 deletions src/mstrap/runtime_managers/mise.cr
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ module MStrap
def set_global_version(language_name, version : String) : Bool
cmd "mise use -g #{plugin_name(language_name)}@#{version}", quiet: true
end

def shell_activation(shell_name : String) : String
<<-SHELL
# Activate mise for language runtime version management
if [ -x "#{MStrap::MiseInstaller::MISE_INSTALL_PATH}" ]; then
export MISE_ASDF_COMPAT=1
eval "$(#{MStrap::MiseInstaller::MISE_INSTALL_PATH} activate #{shell_name})"
eval "$(#{MStrap::MiseInstaller::MISE_INSTALL_PATH} hook-env)"
fi
SHELL
end
end
end
end
2 changes: 2 additions & 0 deletions src/mstrap/steps/debug_step.cr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ module MStrap
puts "mstrap v#{MStrap::VERSION}"
puts "Loaded Config:"
puts " #{options.config_path}"
puts "Default runtime manager:"
puts " #{runtime_manager.name}"
puts "Known Profiles:"
config.known_profile_configs.each do |profile|
puts " #{profile.name}"
Expand Down
21 changes: 18 additions & 3 deletions src/mstrap/steps/dependencies_step.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module MStrap
# and installs software from any available `Brewfile`s.
class DependenciesStep < Step
def self.description
"Basic machine bootstrapping with strap.sh, hub, and brew bundle."
"Basic machine bootstrapping with strap.sh, brew bundle, and other dependencies"
end

def self.requires_mstrap?
Expand All @@ -16,6 +16,7 @@ module MStrap
end

def bootstrap
install_mise if runtime_manager.name == "mise"
set_strap_env!
strap_sh
load_profile!
Expand All @@ -31,7 +32,7 @@ module MStrap
private def strap_sh
logn "==> Running strap.sh"
unless cmd "bash #{MStrap::Paths::STRAP_SH_PATH} #{MStrap.debug? ? "--debug" : ""}"
logc "Uhh oh, something went wrong in strap.sh-land. Check above or in #{MStrap::Paths::LOG_FILE}."
logc "Uhh oh, something went wrong in strap.sh-land."
end
success "Finished running strap.sh"
set_brew_env_if_not_set
Expand All @@ -46,13 +47,27 @@ module MStrap
if File.exists?(brewfile_path)
log "--> Installing dependencies from Brewfile from profile '#{profile_config.name})': "
unless cmd "brew bundle --file=#{brewfile_path} #{MStrap.debug? ? "--verbose" : ""}"
logc "Uhh oh, something went wrong in homebrewland. Check above or in #{MStrap::Paths::LOG_FILE}."
logc "Uhh oh, something went wrong in homebrewland."
end
success "OK"
end
end
end

def install_mise
mise_installer = MiseInstaller.new

log "==> Checking for mise: "
if mise_installer.installed? && !options.force?
success "OK"
else
logn "Not installed".colorize(:yellow)
log "--> Installing mise for language runtime version management: "
mise_installer.install!
success "OK"
end
end

private def load_profile!
log "--> Reloading profile: "
config.reload!
Expand Down
88 changes: 88 additions & 0 deletions src/mstrap/supports/mise_installer.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
module MStrap
# Manages the install of mise for managing language runtimes
#
# NOTE: See `MStrap::RuntimeManagers::Mise` for how mise is integrated
class MiseInstaller
include DSL

# :nodoc:
MISE_INSTALL_SH_PATH = File.join(MStrap::Paths::RC_DIR, "vendor", "mise_install.sh")

# :nodoc:
MISE_INSTALL_SH_URL = "https://mise.jdx.dev/install.sh"

# :nodoc:
MISE_INSTALL_SH_SIG_KEY_ID = "0x24853EC9F655CE80B48E6C3A8B81C9D17413A06D"

# :nodoc:
MISE_INSTALL_SH_SIG_PATH = "#{MISE_INSTALL_SH_PATH}.sig"

# :nodoc:
MISE_INSTALL_SH_SIG_URL = "https://mise.jdx.dev/install.sh.sig"

# :nodoc:
MISE_BIN_DIR_PATH = File.join(MStrap::Paths::RC_DIR, "vendor", "mise", "bin")

# :nodoc:
MISE_INSTALL_PATH = File.join(MISE_BIN_DIR_PATH, "mise")

def initialize(@verify_installer : Bool? = nil)
end

def install!
FileUtils.mkdir_p(MISE_BIN_DIR_PATH)

fetch_installer!

mise_env = {
"MISE_INSTALL_PATH" => MISE_INSTALL_PATH,
}

if MStrap.debug?
mise_env["MISE_DEBUG"] = "1"
else
mise_env["MISE_QUIET"] = "1"
end

cmd mise_env, "sh", [MISE_INSTALL_SH_PATH]

# "Activate" it
path = ENV["PATH"]
ENV["PATH"] = "#{MISE_BIN_DIR_PATH}:#{path}"
end

def installed?
File.exists?(MISE_INSTALL_PATH) && (`command -v mise` && $?.success?)
end

private def fetch_installer!
if verify_installer?
HTTP::Client.get(MISE_INSTALL_SH_SIG_URL, tls: MStrap.tls_client) do |response|
File.write(MISE_INSTALL_SH_SIG_PATH, response.body_io.gets_to_end)
end

unless fetch_installer_public_key && decrypt_installer
logc "Unable to verify mise installer. Signature does not appear to be valid."
end
else
logw "Skipping validation of the mise installer (likely because gpg is not installed or was not found)"
logw "mise will still be downloaded over HTTPS, but we cannot fully validate the authenticity of the installer"
HTTP::Client.get(MISE_INSTALL_SH_URL, tls: MStrap.tls_client) do |response|
File.write(MISE_INSTALL_SH_PATH, response.body_io.gets_to_end)
end
end
end

private def fetch_installer_public_key
cmd "gpg", ["--keyserver", "hkps://keyserver.ubuntu.com", "--recv-keys", MISE_INSTALL_SH_SIG_KEY_ID], quiet: true
end

private def decrypt_installer
cmd "gpg", ["-o", MISE_INSTALL_SH_PATH, "--yes", "--decrypt", MISE_INSTALL_SH_SIG_PATH], quiet: true
end

private def verify_installer?
@verify_installer ||= MStrap::Platform.has_gpg?
end
end
end
2 changes: 0 additions & 2 deletions src/mstrap/templates/Brewfile.ecr
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ brew 'zlib'
# Language runtime managers
<% if runtime_manager.name == "asdf" %>
brew 'asdf'
<% elsif runtime_manager.name == "mise" %>
brew 'mise'
<% end %>

if /darwin/ =~ RUBY_PLATFORM
Expand Down
17 changes: 1 addition & 16 deletions src/mstrap/templates/env.sh.ecr
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,4 @@ export MSTRAP_RC_DIR="<%= MStrap::Paths::RC_DIR %>"
test -d <%= MStrap::Paths::HOMEBREW_PREFIX %> && eval $(<%= MStrap::Paths::HOMEBREW_PREFIX %>/bin/brew shellenv)
<% end -%>

<% if runtime_manager.name == "asdf" %>
# Activate asdf for language runtime version management
if [ -d "$(brew --prefix asdf)" ]; then
source "$(brew --prefix asdf)/libexec/asdf.sh"

if [ ! -f "$HOME/.asdfrc" ]; then
echo "legacy_version_file = yes\n" > "$HOME/.asdfrc"
fi
fi
<% elsif runtime_manager.name == "mise" %>
# Activate mise for language runtime version management
if command -v mise 2>&1 > /dev/null; then
export MISE_ASDF_COMPAT=1
eval "$(mise activate <%= shell_name %>)"
fi
<% end %>
<%= runtime_manager.shell_activation(shell_name) %>

0 comments on commit 7d4cf11

Please sign in to comment.