Skip to content

Commit

Permalink
cmd/{rb,nod}env-sync: add new commands.
Browse files Browse the repository at this point in the history
Add these commands to ease use of Homebrew's bottles with `rbenv` and
`nodenv`.

I've had a lot of people request this over the years and it's worked
well for me for a long time.

I could see people extending these to support other languages or version
managers so perhaps we want a more generic name.
  • Loading branch information
MikeMcQuaid committed Mar 14, 2023
1 parent 7e36b40 commit 3e01fd7
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 0 deletions.
83 changes: 83 additions & 0 deletions Library/Homebrew/cmd/nodenv-sync.rb
@@ -0,0 +1,83 @@
# frozen_string_literal: true

require "cli/parser"
require "formula"

module Homebrew
module_function

def nodenv_sync_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`nodenv-sync`
Create symlinks for Homebrew's installed NodeJS versions in ~/.nodenv/versions.
Note that older version symlinks will also be created so e.g. NodeJS 19.1.0 will
also be symlinked to 19.0.0.
EOS

named_args :none
end
end

def nodenv_sync
dot_nodenv = Pathname(Dir.home)/".nodenv"

# Don't run multiple times at once.
nodenv_sync_running = dot_nodenv/".nodenv_sync_running"
return if nodenv_sync_running.exist?

@nodenv_versions = dot_nodenv/"versions"
@nodenv_versions.mkpath
FileUtils.touch nodenv_sync_running

nodenv_sync_args.parse

HOMEBREW_CELLAR.glob("node{,@*}")
.flat_map(&:children)
.sort_by(&method(:gem_like_version))
.each(&method(:link_nodenv_versions))

@nodenv_versions.children
.select(&:symlink?)
.reject(&:exist?)
.each { |path| FileUtils.rm_f path }
ensure
nodenv_sync_running.unlink if nodenv_sync_running.exist?
end

def gem_like_version(version_path)
Gem::Version.new(version_path.basename
.to_s
.tr("_", "."))
end

def gem_version_segments(version_path)
basename_without_revision = version_path.basename
.to_s
.gsub(/_\d+$/, "")
Gem::Version.new(basename_without_revision)
.canonical_segments
end

def link_version(version_path, version_name, versions_path)
link_path = versions_path / version_name

FileUtils.rm_f link_path
FileUtils.ln_sf version_path, link_path
end

def link_nodenv_versions(version_path)
@nodenv_versions.mkpath

major_version, minor_version, patch_version = gem_version_segments(version_path)
minor_version ||= 0
(0..minor_version).each do |minor|
patch_version ||= 0
(0..patch_version).each do |patch|
link_version(version_path, "#{major_version}.#{minor}.#{patch}", @nodenv_versions)
end
end
end
end
78 changes: 78 additions & 0 deletions Library/Homebrew/cmd/rbenv-sync.rb
@@ -0,0 +1,78 @@
# frozen_string_literal: true

require "cli/parser"
require "formula"

module Homebrew
module_function

def rbenv_sync_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`rbenv-sync`
Create symlinks for Homebrew's installed Ruby versions in ~/.rbenv/versions.
Note that older version symlinks will also be created so e.g. Ruby 3.2.1 will
also be symlinked to 3.2.0.
EOS

named_args :none
end
end

def rbenv_sync
dot_rbenv = Pathname(Dir.home)/".rbenv"

# Don't run multiple times at once.
rbenv_sync_running = dot_rbenv/".rbenv_sync_running"
return if rbenv_sync_running.exist?

@rbenv_versions = dot_rbenv/"versions"
@rbenv_versions.mkpath
FileUtils.touch rbenv_sync_running

rbenv_sync_args.parse

HOMEBREW_CELLAR.glob("ruby{,@*}")
.flat_map(&:children)
.sort_by(&method(:gem_like_version))
.each(&method(:link_rbenv_versions))

@rbenv_versions.children
.select(&:symlink?)
.reject(&:exist?)
.each { |path| FileUtils.rm_f path }
ensure
rbenv_sync_running.unlink if rbenv_sync_running.exist?
end

def gem_like_version(version_path)
Gem::Version.new(version_path.basename
.to_s
.tr("_", "."))
end

def gem_version_segments(version_path)
basename_without_revision = version_path.basename
.to_s
.gsub(/_\d+$/, "")
Gem::Version.new(basename_without_revision)
.canonical_segments
end

def link_version(version_path, version_name, versions_path)
link_path = versions_path/version_name

FileUtils.rm_f link_path
FileUtils.ln_sf version_path, link_path
end

def link_rbenv_versions(version_path)
major_version, minor_version, patch_version = gem_version_segments(version_path)
patch_version ||= 0
(0..patch_version).each do |patch|
link_version(version_path, "#{major_version}.#{minor_version}.#{patch}", @rbenv_versions)
end
end
end

0 comments on commit 3e01fd7

Please sign in to comment.