Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/{rb,nod}env-sync: add new commands.
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
1 parent
7e36b40
commit 3e01fd7
Showing
2 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |