From b61bf2591b32b385e268594f36572e7f72d2ece7 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 14 Mar 2023 13:01:58 -0400 Subject: [PATCH] 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. Co-authored-by: Rylan Polster --- Library/Homebrew/cmd/nodenv-sync.rb | 68 +++++++++++++++++++++++++++++ Library/Homebrew/cmd/rbenv-sync.rb | 66 ++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100755 Library/Homebrew/cmd/nodenv-sync.rb create mode 100755 Library/Homebrew/cmd/rbenv-sync.rb diff --git a/Library/Homebrew/cmd/nodenv-sync.rb b/Library/Homebrew/cmd/nodenv-sync.rb new file mode 100755 index 0000000000..d461e810b8 --- /dev/null +++ b/Library/Homebrew/cmd/nodenv-sync.rb @@ -0,0 +1,68 @@ +# typed: true +# frozen_string_literal: true + +require "cli/parser" +require "formula" + +module Homebrew + module_function + + sig { returns(CLI::Parser) } + def nodenv_sync_args + Homebrew::CLI::Parser.new do + description <<~EOS + 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 + + sig { void } + 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) + .each { |path| link_nodenv_versions(path, 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 + + sig { params(path: Pathname, nodenv_versions: Pathname).void } + def link_nodenv_versions(path, nodenv_versions) + nodenv_versions.mkpath + + version = Keg.new(path).version + major_version = version.major.to_i + minor_version = version.minor.to_i || 0 + patch_version = version.patch.to_i || 0 + + (0..minor_version).each do |minor| + (0..patch_version).each do |patch| + link_path = nodenv_versions/"#{major_version}.#{minor}.#{patch}" + + FileUtils.rm_f link_path + FileUtils.ln_sf path, link_path + end + end + end +end diff --git a/Library/Homebrew/cmd/rbenv-sync.rb b/Library/Homebrew/cmd/rbenv-sync.rb new file mode 100755 index 0000000000..158728e941 --- /dev/null +++ b/Library/Homebrew/cmd/rbenv-sync.rb @@ -0,0 +1,66 @@ +# typed: true +# frozen_string_literal: true + +require "cli/parser" +require "formula" + +module Homebrew + module_function + + sig { returns(CLI::Parser) } + def rbenv_sync_args + Homebrew::CLI::Parser.new do + description <<~EOS + 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 + + sig { void } + 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) + .each { |path| link_rbenv_versions(path, 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 + + sig { params(path: Pathname, rbenv_versions: Pathname).void } + def link_rbenv_versions(path, rbenv_versions) + rbenv_versions.mkpath + + version = Keg.new(path).version + major_version = version.major.to_i + minor_version = version.minor.to_i + patch_version = version.patch.to_i || 0 + + (0..patch_version).each do |patch| + link_path = rbenv_versions/"#{major_version}.#{minor_version}.#{patch}" + + FileUtils.rm_f link_path + FileUtils.ln_sf path, link_path + end + end +end