forked from Homebrew/brew
-
Notifications
You must be signed in to change notification settings - Fork 0
/
update-test.rb
154 lines (130 loc) 路 5.42 KB
/
update-test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# typed: true
# frozen_string_literal: true
require "cli/parser"
module Homebrew
extend T::Sig
sig { returns(CLI::Parser) }
def self.update_test_args
Homebrew::CLI::Parser.new do
description <<~EOS
Run a test of `brew update` with a new repository clone.
If no options are passed, use `origin/master` as the start commit.
EOS
switch "--to-tag",
description: "Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags."
switch "--keep-tmp",
description: "Retain the temporary directory containing the new repository clone."
flag "--commit=",
description: "Use the specified <commit> as the start commit."
flag "--before=",
description: "Use the commit at the specified <date> as the start commit."
named_args :none
end
end
def self.update_test
args = update_test_args.parse
# Avoid `update-report.rb` tapping Homebrew/homebrew-core
ENV["HOMEBREW_UPDATE_TEST"] = "1"
# Avoid accidentally updating when we don't expect it.
ENV["HOMEBREW_NO_AUTO_UPDATE"] = "1"
# Use default behaviours
ENV["HOMEBREW_AUTO_UPDATE_SECS"] = nil
ENV["HOMEBREW_DEVELOPER"] = nil
ENV["HOMEBREW_DEV_CMD_RUN"] = nil
ENV["HOMEBREW_MERGE"] = nil
ENV["HOMEBREW_NO_UPDATE_CLEANUP"] = nil
branch = if args.to_tag?
ENV["HOMEBREW_UPDATE_TO_TAG"] = "1"
"stable"
else
ENV["HOMEBREW_UPDATE_TO_TAG"] = nil
"master"
end
# Utils.popen_read returns a String without a block argument, but that isn't easily typed. We thus label this
# as untyped for now.
start_commit = T.let("", T.untyped)
end_commit = "HEAD"
cd HOMEBREW_REPOSITORY do
start_commit = if (commit = T.let(args.commit, T.nilable(String)))
commit
elsif (date = args.before)
Utils.popen_read("git", "rev-list", "-n1", "--before=#{date}", "origin/master").chomp
elsif args.to_tag?
tags = git_tags
current_tag, previous_tag, = tags.lines
current_tag = current_tag.to_s.chomp
odie "Could not find current tag in:\n#{tags}" if current_tag.empty?
# ^0 ensures this points to the commit rather than the tag object.
end_commit = "#{current_tag}^0"
previous_tag = previous_tag.to_s.chomp
odie "Could not find previous tag in:\n#{tags}" if previous_tag.empty?
# ^0 ensures this points to the commit rather than the tag object.
"#{previous_tag}^0"
else
Utils.popen_read("git", "merge-base", "origin/master", end_commit).chomp
end
odie "Could not find start commit!" if start_commit.empty?
start_commit = Utils.popen_read("git", "rev-parse", start_commit).chomp
odie "Could not find start commit!" if start_commit.empty?
end_commit = T.cast(Utils.popen_read("git", "rev-parse", end_commit).chomp, String)
odie "Could not find end commit!" if end_commit.empty?
if Utils.popen_read("git", "branch", "--list", "master").blank?
safe_system "git", "branch", "master", "origin/master"
end
end
puts <<~EOS
Start commit: #{start_commit}
End commit: #{end_commit}
EOS
mkdir "update-test"
chdir "update-test" do
curdir = Pathname.new(Dir.pwd)
oh1 "Preparing test environment..."
# copy Homebrew installation
safe_system "git", "clone", "#{HOMEBREW_REPOSITORY}/.git", ".",
"--branch", "master", "--single-branch"
# set git origin to another copy
safe_system "git", "clone", "#{HOMEBREW_REPOSITORY}/.git", "remote.git",
"--bare", "--branch", "master", "--single-branch"
safe_system "git", "config", "remote.origin.url", "#{curdir}/remote.git"
ENV["HOMEBREW_BREW_GIT_REMOTE"] = "#{curdir}/remote.git"
# force push origin to end_commit
safe_system "git", "checkout", "-B", "master", end_commit
safe_system "git", "push", "--force", "origin", "master"
# set test copy to start_commit
safe_system "git", "reset", "--hard", start_commit
# update ENV["PATH"]
ENV["PATH"] = PATH.new(ENV.fetch("PATH")).prepend(curdir/"bin").to_s
# run brew help to install portable-ruby (if needed)
quiet_system "brew", "help"
# run brew update
oh1 "Running `brew update`..."
safe_system "brew", "update", "--verbose", "--debug"
actual_end_commit = Utils.popen_read("git", "rev-parse", branch).chomp
if actual_end_commit != end_commit
start_log = Utils.popen_read("git", "log", "-1", "--decorate", "--oneline", start_commit).chomp
end_log = Utils.popen_read("git", "log", "-1", "--decorate", "--oneline", end_commit).chomp
actual_log = Utils.popen_read("git", "log", "-1", "--decorate", "--oneline", actual_end_commit).chomp
odie <<~EOS
`brew update` didn't update #{branch}!
Start commit: #{start_log}
Expected end commit: #{end_log}
Actual end commit: #{actual_log}
EOS
end
end
ensure
FileUtils.rm_rf "update-test" unless args.keep_tmp?
end
def self.git_tags
tags = Utils.popen_read("git", "tag", "--list", "--sort=-version:refname")
if tags.blank?
tags = if (HOMEBREW_REPOSITORY/".git/shallow").exist?
safe_system "git", "fetch", "--tags", "--depth=1"
Utils.popen_read("git", "tag", "--list", "--sort=-version:refname")
end
end
tags
end
end
require "extend/os/dev-cmd/update-test"