From 0a09ae30f8b6117ad699b4a0439010738989c547 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Sat, 17 Sep 2016 14:24:57 +0100 Subject: [PATCH] update-report: migrate /usr/local repository. Migrate a HOMEBREW_REPOSITORY and HOMEBREW_PREFIX of `/usr/local` so that the HOMEBREW_REPOSITORY is now in `/usr/local/Homebrew`. This gives us more flexibility on changing the repository layout in future and avoids putting junk in `/usr/local` when not necessary (e.g. our `README.md`). --- Library/Homebrew/cmd/update-report.rb | 124 ++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index ddbb9bd904..b8c274acc4 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -98,6 +98,9 @@ module Homebrew Tap.each(&:link_manpages) Homebrew.failed = true if ENV["HOMEBREW_UPDATE_FAILED"] + + # This should always be the last thing to run + migrate_legacy_repository_if_necessary end private @@ -169,16 +172,125 @@ module Homebrew end end - def link_completions_and_docs - return if HOMEBREW_PREFIX.to_s == HOMEBREW_REPOSITORY.to_s + def migrate_legacy_repository_if_necessary + return unless HOMEBREW_PREFIX.to_s == "/usr/local" + return unless HOMEBREW_REPOSITORY.to_s == "/usr/local" + return unless ARGV.homebrew_developer? + + ohai "Migrating HOMEBREW_REPOSITORY (please wait)..." + + unless HOMEBREW_PREFIX.writable_real? + ofail <<-EOS.undent + #{HOMEBREW_PREFIX} is not writable. + + You should change the ownership and permissions of #{HOMEBREW_PREFIX} + temporarily back to your user account so we can complete the Homebrew + repository migration: + sudo chown -R $(whoami) #{HOMEBREW_PREFIX} + EOS + return + end + + Keg::ALL_TOP_LEVEL_DIRECTORIES.each do |dir| + FileUtils.mkdir_p "#{HOMEBREW_PREFIX}/#{dir}" + end + + new_homebrew_repository = Pathname.new "/usr/local/Homebrew" + if new_homebrew_repository.exist? + ofail <<-EOS.undent + #{new_homebrew_repository} already exists. + Please remove it manually or uninstall and reinstall Homebrew into a new + location as the migration cannot be done automatically. + EOS + return + end + new_homebrew_repository.mkpath + + repo_files = HOMEBREW_REPOSITORY.cd do + Utils.popen_read("git ls-files").lines.map(&:chomp) + end + + unless Utils.popen_read("git status --untracked-files=all --porcelain").empty? + HOMEBREW_REPOSITORY.cd do + safe_system "git", "-c", "user.email=brew-update@localhost", + "-c", "user.name=brew update", + "stash", "save", "--include-untracked" + end + stashed = true + end + + FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/.git", "#{new_homebrew_repository}/.git" + new_homebrew_repository.cd do + safe_system "git", "checkout", "--force", "." + safe_system "git", "stash", "pop" if stashed + end + + if (HOMEBREW_REPOSITORY/"Library/Locks").exist? + FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/Library/Locks", "#{new_homebrew_repository}/Library/Locks" + end + + if (HOMEBREW_REPOSITORY/"Library/Taps").exist? + FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/Library/Taps", "#{new_homebrew_repository}/Library/Taps" + end + + unremovable_paths = [] + extra_remove_paths = [".git", "Library/Locks", "Library/Taps", + "Library/Homebrew/test"] + (repo_files + extra_remove_paths).each do |file| + path = Pathname.new "#{HOMEBREW_REPOSITORY}/#{file}" + begin + FileUtils.rm_rf path + rescue Errno::EACCES + unremovable_paths << path + end + quiet_system "rmdir", "-p", path.parent if path.parent.exist? + end + + unless unremovable_paths.empty? + ofail <<-EOS.undent + Could not remove old HOMEBREW_REPOSITORY paths! + Please do this manually with: + sudo rm -rf #{unremovable_paths.join " "} + EOS + end + + src = Pathname.new("#{new_homebrew_repository}/bin/brew") + dst = Pathname.new("#{HOMEBREW_PREFIX}/bin/brew") + begin + FileUtils.ln_s(src.relative_path_from(dst.parent), dst) + rescue Errno::EACCES + ofail <<-EOS.undent + Could not create symlink at #{dst}! + Please do this manually with: + sudo ln -sf #{src} #{dst} + sudo chown $(whoami) #{dst} + EOS + end + + link_completions_and_docs(new_homebrew_repository) + + ohai "Migrated HOMEBREW_REPOSITORY to #{new_homebrew_repository}!" + puts "You may now chown #{HOMEBREW_PREFIX} back to root:wheel." + rescue => e + ofail <<-EOS.undent + #{e} + #{Tty.white}Failed to migrate HOMEBREW_REPOSITORY to #{new_homebrew_repository}! + Please comment with your (new) error in issue: + #{Tty.em}https://github.com/Homebrew/brew/issues/987#{Tty.reset} + EOS + $stderr.puts e.backtrace + end + + def link_completions_and_docs(repository = HOMEBREW_REPOSITORY) + return if HOMEBREW_PREFIX.to_s == repository.to_s command = "brew update" - link_src_dst_dirs(HOMEBREW_REPOSITORY/"etc/bash_completion.d", + link_src_dst_dirs(repository/"etc/bash_completion.d", HOMEBREW_PREFIX/"etc/bash_completion.d", command) - link_src_dst_dirs(HOMEBREW_REPOSITORY/"share/doc/homebrew", + link_src_dst_dirs(repository/"share/doc/homebrew", HOMEBREW_PREFIX/"share/doc/homebrew", command, link_dir: true) - link_src_dst_dirs(HOMEBREW_REPOSITORY/"share/zsh/site-functions", + link_src_dst_dirs(repository/"share/zsh/site-functions", HOMEBREW_PREFIX/"share/zsh/site-functions", command) - link_path_manpages(HOMEBREW_REPOSITORY/"share", command) + link_path_manpages(repository/"share", command) end end