Add new update-bash command for testing.
This will become the default updater at a later point in the future.
This commit is contained in:
parent
6f91b429ce
commit
99234f0256
280
Library/Homebrew/cmd/update-bash.sh
Executable file
280
Library/Homebrew/cmd/update-bash.sh
Executable file
@ -0,0 +1,280 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -z "$HOMEBREW_BREW_FILE" ]
|
||||||
|
then
|
||||||
|
echo "Error: $(basename "$0") must be called from brew!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
brew() {
|
||||||
|
"$HOMEBREW_BREW_FILE" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
which_git() {
|
||||||
|
local which_git
|
||||||
|
which_git="$(which git 2>/dev/null)"
|
||||||
|
if [ -n "$which_git" ] && [ "/usr/bin/git" = "$which_git" ]
|
||||||
|
then
|
||||||
|
local active_developer_dir
|
||||||
|
active_developer_dir="$('/usr/bin/xcode-select' -print-path 2>/dev/null)"
|
||||||
|
if [ -n "$active_developer_dir" ] && [ -x "$active_developer_dir/usr/bin/git" ]
|
||||||
|
then
|
||||||
|
which_git="$active_developer_dir/usr/bin/git"
|
||||||
|
else
|
||||||
|
which_git=""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$which_git"
|
||||||
|
}
|
||||||
|
|
||||||
|
git_init_if_necessary() {
|
||||||
|
if ! [ -d ".git" ]
|
||||||
|
then
|
||||||
|
git init -q
|
||||||
|
git config --bool core.autocrlf false
|
||||||
|
git config remote.origin.url https://github.com/Homebrew/homebrew.git
|
||||||
|
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git remote show origin -n | grep -q "mxcl/homebrew"
|
||||||
|
then
|
||||||
|
git remote set-url origin https://github.com/Homebrew/homebrew.git
|
||||||
|
git remote set-url --delete origin ".*mxcl\/homebrew.*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
repo_var() {
|
||||||
|
echo "$1" |
|
||||||
|
sed -e "s|$HOMEBREW_PREFIX||g" \
|
||||||
|
-e 's|Library/Taps/||g' \
|
||||||
|
-e 's|[^a-z0-9]|_|g' |
|
||||||
|
tr "[:lower:]" "[:upper:]"
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream_branch() {
|
||||||
|
local upstream_branch
|
||||||
|
upstream_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null |
|
||||||
|
sed -e 's|refs/remotes/origin/||' )"
|
||||||
|
[ -z "$upstream_branch" ] && upstream_branch="master"
|
||||||
|
echo "$upstream_branch"
|
||||||
|
}
|
||||||
|
|
||||||
|
read_current_revision() {
|
||||||
|
git rev-parse -q --verify HEAD
|
||||||
|
}
|
||||||
|
|
||||||
|
# Don't warn about QUIET_ARGS; they need to be unquoted.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
pop_stash() {
|
||||||
|
[ -z "$STASHED" ] && return
|
||||||
|
git stash pop $QUIET_ARGS
|
||||||
|
if [ -n "$HOMEBREW_VERBOSE" ]
|
||||||
|
then
|
||||||
|
echo "Restoring your stashed changes to $DIR:"
|
||||||
|
git status --short --untracked-files
|
||||||
|
fi
|
||||||
|
unset STASHED
|
||||||
|
}
|
||||||
|
|
||||||
|
pop_stash_message() {
|
||||||
|
[ -z "$STASHED" ] && return
|
||||||
|
echo "To restore the stashed changes to $DIR run:"
|
||||||
|
echo " 'cd $DIR && git stash pop'"
|
||||||
|
unset STASHED
|
||||||
|
}
|
||||||
|
|
||||||
|
# Don't warn about QUIET_ARGS; they need to be unquoted.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
reset_on_interrupt() {
|
||||||
|
[ -z "$INITIAL_BRANCH" ] || git checkout "$INITIAL_BRANCH"
|
||||||
|
git reset --hard "$INITIAL_REVISION" $QUIET_ARGS
|
||||||
|
if [ -n "$INITIAL_BRANCH" ]
|
||||||
|
then
|
||||||
|
pop_stash
|
||||||
|
else
|
||||||
|
pop_stash_message
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Don't warn about QUIET_ARGS; they need to be unquoted.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
pull() {
|
||||||
|
local DIR="$1"
|
||||||
|
cd "$DIR" || return
|
||||||
|
TAP_VAR=$(repo_var "$DIR")
|
||||||
|
unset STASHED
|
||||||
|
|
||||||
|
# The upstream repository's default branch may not be master;
|
||||||
|
# check refs/remotes/origin/HEAD to see what the default
|
||||||
|
# origin branch name is, and use that. If not set, fall back to "master".
|
||||||
|
INITIAL_BRANCH="$(git symbolic-ref --short HEAD 2>/dev/null)"
|
||||||
|
UPSTREAM_BRANCH="$(upstream_branch)"
|
||||||
|
|
||||||
|
if [ -n "$(git status --untracked-files=all --porcelain 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
if [ -n "$HOMEBREW_VERBOSE" ]
|
||||||
|
then
|
||||||
|
echo "Stashing uncommitted changes to $DIR."
|
||||||
|
git status --short --untracked-files=all
|
||||||
|
fi
|
||||||
|
git -c "user.email=brew-update@localhost" \
|
||||||
|
-c "user.name=brew update" \
|
||||||
|
stash save --include-untracked $QUIET_ARGS
|
||||||
|
git reset --hard $QUIET_ARGS
|
||||||
|
STASHED="1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Used for testing purposes, e.g., for testing formula migration after
|
||||||
|
# renaming it in the currently checked-out branch. To test run
|
||||||
|
# "brew update --simulate-from-current-branch"
|
||||||
|
if [ -n "$HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH" ]
|
||||||
|
then
|
||||||
|
INITIAL_REVISION="$(git rev-parse -q --verify "$(upstream_branch)")"
|
||||||
|
CURRENT_REVISION="$(read_current_revision)"
|
||||||
|
export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$(git rev-parse "$UPSTREAM_BRANCH")"
|
||||||
|
if ! git merge-base --is-ancestor "$INITIAL_REVISION" "$CURRENT_REVISION"
|
||||||
|
then
|
||||||
|
echo "Your HEAD is not a descendant of $UPSTREAM_BRANCH!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$INITIAL_BRANCH" != "$UPSTREAM_BRANCH" ] && [ -n "$INITIAL_BRANCH" ]
|
||||||
|
then
|
||||||
|
# Recreate and check out `#{upstream_branch}` if unable to fast-forward
|
||||||
|
# it to `origin/#{@upstream_branch}`. Otherwise, just check it out.
|
||||||
|
if git merge-base --is-ancestor "$UPSTREAM_BRANCH" "origin/$UPSTREAM_BRANCH" &>/dev/null
|
||||||
|
then
|
||||||
|
git checkout --force "$UPSTREAM_BRANCH" $QUIET_ARGS
|
||||||
|
else
|
||||||
|
git checkout --force -B "$UPSTREAM_BRANCH" "origin/$UPSTREAM_BRANCH" $QUIET_ARGS
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
INITIAL_REVISION="$(read_current_revision)"
|
||||||
|
|
||||||
|
# ensure we don't munge line endings on checkout
|
||||||
|
git config core.autocrlf false
|
||||||
|
|
||||||
|
trap reset_on_interrupt SIGINT
|
||||||
|
|
||||||
|
if [ -n "$HOMEBREW_REBASE" ]
|
||||||
|
then
|
||||||
|
git rebase $QUIET_ARGS "origin/$UPSTREAM_BRANCH"
|
||||||
|
else
|
||||||
|
git merge --no-edit --ff $QUIET_ARGS "origin/$UPSTREAM_BRANCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap - SIGINT
|
||||||
|
|
||||||
|
CURRENT_REVISION="$(read_current_revision)"
|
||||||
|
export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$(git rev-parse "$UPSTREAM_BRANCH")"
|
||||||
|
|
||||||
|
if [ "$INITIAL_BRANCH" != "$UPSTREAM_BRANCH" ] && [ -n "$INITIAL_BRANCH" ]
|
||||||
|
then
|
||||||
|
git checkout "$INITIAL_BRANCH" $QUIET_ARGS
|
||||||
|
pop_stash
|
||||||
|
else
|
||||||
|
pop_stash_message
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update-bash() {
|
||||||
|
if [ -z "$HOMEBREW_DEVELOPER" ]
|
||||||
|
then
|
||||||
|
echo "This command is currently only for Homebrew developers' use." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in "$@"
|
||||||
|
do
|
||||||
|
case "$i" in
|
||||||
|
update|update-bash) shift ;;
|
||||||
|
--help) brew update --help; exit $? ;;
|
||||||
|
--verbose) HOMEBREW_VERBOSE=1 ;;
|
||||||
|
--debug) HOMEBREW_DEBUG=1;;
|
||||||
|
--rebase) HOMEBREW_REBASE=1 ;;
|
||||||
|
--simulate-from-current-branch) HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH=1 ;;
|
||||||
|
--*) ;;
|
||||||
|
-*v*) HOMEBREW_VERBOSE=1 ;;
|
||||||
|
-*v*) HOMEBREW_DEBUG=1 ;;
|
||||||
|
-*) ;;
|
||||||
|
*)
|
||||||
|
echo "This command updates brew itself, and does not take formula names." >&2
|
||||||
|
echo "Use 'brew upgrade <formula>'." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$HOMEBREW_DEBUG" ]
|
||||||
|
then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check permissions
|
||||||
|
if [ "$HOMEBREW_PREFIX" = "/usr/local" ] && ! test -w /usr/local
|
||||||
|
then
|
||||||
|
echo "Error: /usr/local must be writable!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -w "$HOMEBREW_REPOSITORY"
|
||||||
|
then
|
||||||
|
echo "Error: $HOMEBREW_REPOSITORY must be writable!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$(which_git)" ]
|
||||||
|
then
|
||||||
|
brew install git
|
||||||
|
if [ -z "$(which_git)" ]
|
||||||
|
then
|
||||||
|
echo "Error: Git must be installed and in your PATH!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$HOMEBREW_VERBOSE" ]
|
||||||
|
then
|
||||||
|
QUIET_ARGS="-q"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ensure GIT_CONFIG is unset as we need to operate on .git/config
|
||||||
|
unset GIT_CONFIG
|
||||||
|
|
||||||
|
cd "$HOMEBREW_REPOSITORY" || {
|
||||||
|
echo "Error: failed to cd to $HOMEBREW_REPOSITORY!" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
git_init_if_necessary
|
||||||
|
|
||||||
|
for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/*
|
||||||
|
do
|
||||||
|
[ -d "$DIR/.git" ] || continue
|
||||||
|
cd "$DIR" || continue
|
||||||
|
TAP_VAR=$(repo_var "$DIR")
|
||||||
|
export HOMEBREW_UPDATE_BEFORE"$TAP_VAR"="$(git rev-parse "$(upstream_branch)")"
|
||||||
|
UPSTREAM_BRANCH="$(upstream_branch)"
|
||||||
|
# the refspec ensures that the default upstream branch gets updated
|
||||||
|
git fetch $QUIET_ARGS origin \
|
||||||
|
"refs/heads/$UPSTREAM_BRANCH:refs/remotes/origin/$UPSTREAM_BRANCH" &
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/*
|
||||||
|
do
|
||||||
|
[ -d "$DIR/.git" ] || continue
|
||||||
|
pull "$DIR"
|
||||||
|
done
|
||||||
|
|
||||||
|
cd "$HOMEBREW_REPOSITORY" || {
|
||||||
|
echo "Error: failed to cd to $HOMEBREW_REPOSITORY!" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
brew update-report "$@"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
351
Library/Homebrew/cmd/update-report.rb
Normal file
351
Library/Homebrew/cmd/update-report.rb
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
require "cmd/tap"
|
||||||
|
require "formula_versions"
|
||||||
|
require "migrator"
|
||||||
|
require "formulary"
|
||||||
|
require "descriptions"
|
||||||
|
|
||||||
|
module Homebrew
|
||||||
|
def update_report
|
||||||
|
unless ENV["HOMEBREW_DEVELOPER"]
|
||||||
|
odie "This command is currently only for Homebrew developers' use."
|
||||||
|
end
|
||||||
|
|
||||||
|
# migrate to new directories based tap structure
|
||||||
|
migrate_taps
|
||||||
|
|
||||||
|
report = Report.new
|
||||||
|
master_updater = Reporter.new(HOMEBREW_REPOSITORY)
|
||||||
|
master_updated = master_updater.updated?
|
||||||
|
if master_updated
|
||||||
|
initial_short = shorten_revision(master_updater.initial_revision)
|
||||||
|
current_short = shorten_revision(master_updater.current_revision)
|
||||||
|
puts "Updated Homebrew from #{initial_short} to #{current_short}."
|
||||||
|
end
|
||||||
|
report.update(master_updater.report)
|
||||||
|
|
||||||
|
# rename Taps directories
|
||||||
|
# this procedure will be removed in the future if it seems unnecessasry
|
||||||
|
rename_taps_dir_if_necessary
|
||||||
|
|
||||||
|
updated_taps = []
|
||||||
|
Tap.each do |tap|
|
||||||
|
tap.path.cd do
|
||||||
|
updater = Reporter.new(tap.path)
|
||||||
|
updated_taps << tap.name if updater.updated?
|
||||||
|
report.update(updater.report) do |_key, oldval, newval|
|
||||||
|
oldval.concat(newval)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unless updated_taps.empty?
|
||||||
|
puts "Updated #{updated_taps.size} tap#{plural(updated_taps.size)} " \
|
||||||
|
"(#{updated_taps.join(", ")})."
|
||||||
|
end
|
||||||
|
puts "Already up-to-date." unless master_updated || !updated_taps.empty?
|
||||||
|
|
||||||
|
Tap.clear_cache
|
||||||
|
Tap.each(&:link_manpages)
|
||||||
|
|
||||||
|
# automatically tap any migrated formulae's new tap
|
||||||
|
report.select_formula(:D).each do |f|
|
||||||
|
next unless (dir = HOMEBREW_CELLAR/f).exist?
|
||||||
|
migration = TAP_MIGRATIONS[f]
|
||||||
|
next unless migration
|
||||||
|
tap = Tap.fetch(*migration.split("/"))
|
||||||
|
tap.install unless tap.installed?
|
||||||
|
|
||||||
|
# update tap for each Tab
|
||||||
|
tabs = dir.subdirs.map { |d| Tab.for_keg(Keg.new(d)) }
|
||||||
|
next if tabs.first.source["tap"] != "Homebrew/homebrew"
|
||||||
|
tabs.each { |tab| tab.source["tap"] = "#{tap.user}/homebrew-#{tap.repo}" }
|
||||||
|
tabs.each(&:write)
|
||||||
|
end if load_tap_migrations
|
||||||
|
|
||||||
|
load_formula_renames
|
||||||
|
report.update_renamed
|
||||||
|
|
||||||
|
# Migrate installed renamed formulae from core and taps.
|
||||||
|
report.select_formula(:R).each do |oldname, newname|
|
||||||
|
if oldname.include?("/")
|
||||||
|
user, repo, oldname = oldname.split("/", 3)
|
||||||
|
newname = newname.split("/", 3).last
|
||||||
|
else
|
||||||
|
user = "homebrew"
|
||||||
|
repo = "homebrew"
|
||||||
|
end
|
||||||
|
|
||||||
|
next unless (dir = HOMEBREW_CELLAR/oldname).directory? && !dir.subdirs.empty?
|
||||||
|
|
||||||
|
begin
|
||||||
|
f = Formulary.factory("#{user}/#{repo}/#{newname}")
|
||||||
|
# short term fix to prevent situation like https://github.com/Homebrew/homebrew/issues/45616
|
||||||
|
rescue Exception
|
||||||
|
end
|
||||||
|
|
||||||
|
next unless f
|
||||||
|
|
||||||
|
begin
|
||||||
|
migrator = Migrator.new(f)
|
||||||
|
migrator.migrate
|
||||||
|
rescue Migrator::MigratorDifferentTapsError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if report.empty?
|
||||||
|
puts "No changes to formulae." if master_updated || !updated_taps.empty?
|
||||||
|
else
|
||||||
|
report.dump
|
||||||
|
end
|
||||||
|
Descriptions.update_cache(report)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def shorten_revision(revision)
|
||||||
|
`git rev-parse --short #{revision}`.chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def rename_taps_dir_if_necessary
|
||||||
|
Dir.glob("#{HOMEBREW_LIBRARY}/Taps/*/") do |tapd|
|
||||||
|
begin
|
||||||
|
if File.directory?(tapd + "/.git")
|
||||||
|
tapd_basename = File.basename(tapd)
|
||||||
|
if tapd_basename.include?("-")
|
||||||
|
# only replace the *last* dash: yes, tap filenames suck
|
||||||
|
user, repo = tapd_basename.reverse.sub("-", "/").reverse.split("/")
|
||||||
|
|
||||||
|
FileUtils.mkdir_p("#{HOMEBREW_LIBRARY}/Taps/#{user.downcase}")
|
||||||
|
FileUtils.mv(tapd, "#{HOMEBREW_LIBRARY}/Taps/#{user.downcase}/homebrew-#{repo.downcase}")
|
||||||
|
|
||||||
|
if tapd_basename.count("-") >= 2
|
||||||
|
opoo "Homebrew changed the structure of Taps like <someuser>/<sometap>. "\
|
||||||
|
+ "So you may need to rename #{HOMEBREW_LIBRARY}/Taps/#{user.downcase}/homebrew-#{repo.downcase} manually."
|
||||||
|
end
|
||||||
|
else
|
||||||
|
opoo "Homebrew changed the structure of Taps like <someuser>/<sometap>. "\
|
||||||
|
"#{tapd} is incorrect name format. You may need to rename it like <someuser>/<sometap> manually."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue => ex
|
||||||
|
onoe ex.message
|
||||||
|
next # next tap directory
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_tap_migrations
|
||||||
|
load "tap_migrations.rb"
|
||||||
|
rescue LoadError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_formula_renames
|
||||||
|
load "formula_renames.rb"
|
||||||
|
rescue LoadError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Reporter
|
||||||
|
attr_reader :initial_revision, :current_revision, :repository
|
||||||
|
|
||||||
|
def self.repository_variable(repository)
|
||||||
|
repository.to_s.
|
||||||
|
gsub("#{HOMEBREW_PREFIX}", "").
|
||||||
|
gsub("Library/Taps/", "").
|
||||||
|
gsub(/[^a-z0-9]/, "_").
|
||||||
|
upcase
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(repository)
|
||||||
|
@repository = repository
|
||||||
|
|
||||||
|
repo_var = Reporter.repository_variable(@repository)
|
||||||
|
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
|
||||||
|
@initial_revision = ENV[initial_revision_var].to_s
|
||||||
|
if @initial_revision.empty?
|
||||||
|
raise "#{initial_revision_var} is unset!" if ARGV.homebrew_developer?
|
||||||
|
raise "update-report should not be called directly!"
|
||||||
|
end
|
||||||
|
|
||||||
|
current_revision_var = "HOMEBREW_UPDATE_AFTER#{repo_var}"
|
||||||
|
@current_revision = ENV[current_revision_var].to_s
|
||||||
|
if @current_revision.empty?
|
||||||
|
raise "#{current_revision_var} is unset!" if ARGV.homebrew_developer?
|
||||||
|
raise "update-report should not be called directly!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def report
|
||||||
|
map = Hash.new { |h, k| h[k] = [] }
|
||||||
|
|
||||||
|
if initial_revision && initial_revision != current_revision
|
||||||
|
wc_revision = read_current_revision
|
||||||
|
|
||||||
|
diff.each_line do |line|
|
||||||
|
status, *paths = line.split
|
||||||
|
src = paths.first
|
||||||
|
dst = paths.last
|
||||||
|
|
||||||
|
next unless File.extname(dst) == ".rb"
|
||||||
|
next unless paths.any? { |p| File.dirname(p) == formula_directory }
|
||||||
|
|
||||||
|
case status
|
||||||
|
when "A", "D"
|
||||||
|
map[status.to_sym] << repository.join(src)
|
||||||
|
when "M"
|
||||||
|
file = repository.join(src)
|
||||||
|
begin
|
||||||
|
formula = Formulary.factory(file)
|
||||||
|
new_version = if wc_revision == current_revision
|
||||||
|
formula.pkg_version
|
||||||
|
else
|
||||||
|
FormulaVersions.new(formula).formula_at_revision(@current_revision, &:pkg_version)
|
||||||
|
end
|
||||||
|
old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)
|
||||||
|
next if new_version == old_version
|
||||||
|
# short term fix to prevent situation like https://github.com/Homebrew/homebrew/issues/45616
|
||||||
|
rescue Exception => e
|
||||||
|
onoe e if ARGV.homebrew_developer?
|
||||||
|
end
|
||||||
|
map[:M] << file
|
||||||
|
when /^R\d{0,3}/
|
||||||
|
map[:D] << repository.join(src) if File.dirname(src) == formula_directory
|
||||||
|
map[:A] << repository.join(dst) if File.dirname(dst) == formula_directory
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
map
|
||||||
|
end
|
||||||
|
|
||||||
|
def updated?
|
||||||
|
initial_revision && initial_revision != current_revision
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def formula_directory
|
||||||
|
if repository == HOMEBREW_REPOSITORY
|
||||||
|
"Library/Formula"
|
||||||
|
elsif repository.join("Formula").directory?
|
||||||
|
"Formula"
|
||||||
|
elsif repository.join("HomebrewFormula").directory?
|
||||||
|
"HomebrewFormula"
|
||||||
|
else
|
||||||
|
"."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_current_revision
|
||||||
|
`git rev-parse -q --verify HEAD`.chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def diff
|
||||||
|
Utils.popen_read(
|
||||||
|
"git", "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
|
||||||
|
"-M85%", initial_revision, current_revision
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def `(cmd)
|
||||||
|
out = super
|
||||||
|
unless $?.success?
|
||||||
|
$stderr.puts(out) unless out.empty?
|
||||||
|
raise ErrorDuringExecution.new(cmd)
|
||||||
|
end
|
||||||
|
ohai(cmd, out) if ARGV.verbose?
|
||||||
|
out
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Report
|
||||||
|
def initialize
|
||||||
|
@hash = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch(*args, &block)
|
||||||
|
@hash.fetch(*args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(*args, &block)
|
||||||
|
@hash.update(*args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def empty?
|
||||||
|
@hash.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def dump
|
||||||
|
# Key Legend: Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
|
||||||
|
|
||||||
|
dump_formula_report :A, "New Formulae"
|
||||||
|
dump_formula_report :M, "Updated Formulae"
|
||||||
|
dump_formula_report :R, "Renamed Formulae"
|
||||||
|
dump_formula_report :D, "Deleted Formulae"
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_renamed
|
||||||
|
renamed_formulae = []
|
||||||
|
|
||||||
|
fetch(:D, []).each do |path|
|
||||||
|
case path.to_s
|
||||||
|
when HOMEBREW_TAP_PATH_REGEX
|
||||||
|
oldname = path.basename(".rb").to_s
|
||||||
|
next unless newname = Tap.fetch($1, $2).formula_renames[oldname]
|
||||||
|
else
|
||||||
|
oldname = path.basename(".rb").to_s
|
||||||
|
next unless newname = CoreFormulaRepository.instance.formula_renames[oldname]
|
||||||
|
end
|
||||||
|
|
||||||
|
if fetch(:A, []).include?(newpath = path.dirname.join("#{newname}.rb"))
|
||||||
|
renamed_formulae << [path, newpath]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless renamed_formulae.empty?
|
||||||
|
@hash[:A] -= renamed_formulae.map(&:last) if @hash[:A]
|
||||||
|
@hash[:D] -= renamed_formulae.map(&:first) if @hash[:D]
|
||||||
|
@hash[:R] = renamed_formulae
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_formula(key)
|
||||||
|
fetch(key, []).map do |path, newpath|
|
||||||
|
if path.to_s =~ HOMEBREW_TAP_PATH_REGEX
|
||||||
|
tap = Tap.fetch($1, $2)
|
||||||
|
if newpath
|
||||||
|
["#{tap}/#{path.basename(".rb")}", "#{tap}/#{newpath.basename(".rb")}"]
|
||||||
|
else
|
||||||
|
"#{tap}/#{path.basename(".rb")}"
|
||||||
|
end
|
||||||
|
elsif newpath
|
||||||
|
["#{path.basename(".rb")}", "#{newpath.basename(".rb")}"]
|
||||||
|
else
|
||||||
|
path.basename(".rb").to_s
|
||||||
|
end
|
||||||
|
end.sort
|
||||||
|
end
|
||||||
|
|
||||||
|
def dump_formula_report(key, title)
|
||||||
|
formula = select_formula(key).map do |name, new_name|
|
||||||
|
# Format list items of renamed formulae
|
||||||
|
if key == :R
|
||||||
|
new_name = pretty_installed(new_name) if installed?(name)
|
||||||
|
"#{name} -> #{new_name}"
|
||||||
|
else
|
||||||
|
installed?(name) ? pretty_installed(name) : name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless formula.empty?
|
||||||
|
# Dump formula list.
|
||||||
|
ohai title
|
||||||
|
puts_columns(formula)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def installed?(formula)
|
||||||
|
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
||||||
|
end
|
||||||
|
end
|
||||||
106
Library/Homebrew/test/test_update_report.rb
Normal file
106
Library/Homebrew/test/test_update_report.rb
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
require "testing_env"
|
||||||
|
require "cmd/update-report"
|
||||||
|
require "formula_versions"
|
||||||
|
require "yaml"
|
||||||
|
|
||||||
|
class ReportTests < Homebrew::TestCase
|
||||||
|
class ReporterMock < ::Reporter
|
||||||
|
attr_accessor :diff, :expected, :called
|
||||||
|
|
||||||
|
def initialize(repository)
|
||||||
|
repo_var = Reporter.repository_variable(repository)
|
||||||
|
ENV["HOMEBREW_UPDATE_BEFORE#{repo_var}"] = "abcdef12"
|
||||||
|
ENV["HOMEBREW_UPDATE_AFTER#{repo_var}"] = "abcdef12"
|
||||||
|
super
|
||||||
|
@outputs = Hash.new { |h, k| h[k] = [] }
|
||||||
|
@expected = []
|
||||||
|
@called = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_repo_expect(cmd, output = "")
|
||||||
|
@expected << cmd
|
||||||
|
@outputs[cmd] << output
|
||||||
|
end
|
||||||
|
|
||||||
|
def `(*args)
|
||||||
|
cmd = args.join(" ")
|
||||||
|
if @expected.include?(cmd) && !@outputs[cmd].empty?
|
||||||
|
@called << cmd
|
||||||
|
@outputs[cmd].shift
|
||||||
|
else
|
||||||
|
raise "#{inspect} unexpectedly called backticks: `#{cmd}`"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
alias_method :safe_system, :`
|
||||||
|
alias_method :system, :`
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<#{self.class.name}>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fixture(name)
|
||||||
|
self.class.fixture_data[name] || ""
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.fixture_data
|
||||||
|
@fixture_data ||= YAML.load_file("#{TEST_DIRECTORY}/fixtures/updater_fixture.yaml")
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@updater = ReporterMock.new(HOMEBREW_REPOSITORY)
|
||||||
|
@report = Report.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.rm_rf HOMEBREW_LIBRARY.join("Taps")
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform_update(fixture_name = "")
|
||||||
|
Formulary.stubs(:factory).returns(stub(:pkg_version => "1.0"))
|
||||||
|
FormulaVersions.stubs(:new).returns(stub(:formula_at_revision => "2.0"))
|
||||||
|
@updater.diff = fixture(fixture_name)
|
||||||
|
@report.update(@updater.report)
|
||||||
|
assert_equal @updater.expected, @updater.called
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_without_any_changes
|
||||||
|
perform_update
|
||||||
|
assert_empty @report
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_without_formulae_changes
|
||||||
|
perform_update("update_git_diff_output_without_formulae_changes")
|
||||||
|
assert_empty @report.select_formula(:M)
|
||||||
|
assert_empty @report.select_formula(:A)
|
||||||
|
assert_empty @report.select_formula(:D)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_with_changed_filetype
|
||||||
|
perform_update("update_git_diff_output_with_changed_filetype")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_with_restructured_tap
|
||||||
|
repo = HOMEBREW_LIBRARY.join("Taps", "foo", "bar")
|
||||||
|
@updater = ReporterMock.new(repo)
|
||||||
|
repo.join("Formula").mkpath
|
||||||
|
|
||||||
|
perform_update("update_git_diff_output_with_restructured_tap")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_simulate_homebrew_php_restructuring
|
||||||
|
repo = HOMEBREW_LIBRARY.join("Taps", "foo", "bar")
|
||||||
|
@updater = ReporterMock.new(repo)
|
||||||
|
repo.join("Formula").mkpath
|
||||||
|
|
||||||
|
perform_update("update_git_diff_simulate_homebrew_php_restructuring")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update_homebrew_with_tap_formulae_changes
|
||||||
|
repo = HOMEBREW_LIBRARY.join("Taps", "foo", "bar")
|
||||||
|
@updater = ReporterMock.new(repo)
|
||||||
|
repo.join("Formula").mkpath
|
||||||
|
|
||||||
|
perform_update("update_git_diff_output_with_tap_formulae_changes")
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user