Last active
April 12, 2022 16:14
-
-
Save kateinoigakukun/2a4c7840a1efc8e4ab2a78de7e9d4aa5 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# $ ruby ./bisect-toolchain-snapshot.rb swift-wasm-DEVELOPMENT-SNAPSHOT-2021-12-12-a swift-wasm-DEVELOPMENT-SNAPSHOT-2022-04-06-a run.sh --workdir /tmp/toolchain-bisect | |
require "date" | |
require "net/http" | |
require "json" | |
require "tmpdir" | |
def bisect_date_seq(candidates) | |
bad = 0 | |
good = candidates.length - 1 | |
loop do | |
mid = bad + (good - bad) / 2 | |
break if mid == good or mid == bad | |
puts "select #{candidates[mid]["tag_name"]}, good = #{candidates[good]["tag_name"]}, bad = #{candidates[bad]["tag_name"]}" | |
ok = yield candidates[mid] | |
if ok | |
good = mid | |
else | |
bad = mid | |
end | |
end | |
candidates[bad] | |
end | |
def snapshot_exist?(tag_name, date) | |
uri = URI.parse("https://api.github.com/repos/swiftwasm/swift/releases/tags/#{tag_name}") | |
p uri | |
response = Net::HTTP.get_response(uri) | |
if response.code == "200" | |
true | |
else | |
puts "Got #{response}" | |
false | |
end | |
end | |
def fetch_snapshot(tag_name, workdir) | |
snapshot_uri = "https://github.com/swiftwasm/swift/releases/download/#{tag_name}/#{tag_name}-ubuntu20.04_x86_64.tar.gz" | |
dir = File.join(workdir, tag_name) | |
toolchain_dir = File.join(dir, tag_name) | |
return toolchain_dir if Dir.exist?(toolchain_dir) | |
Dir.mkdir(dir) unless Dir.exist?(dir) | |
puts "Fetching #{snapshot_uri} in #{dir} ..." | |
Dir.chdir(dir) do | |
raise "failed to fetch" unless system("curl -L #{snapshot_uri} | tar xz") | |
end | |
toolchain_dir | |
end | |
def github_get_response(uri) | |
headers = {} | |
headers["Authorization"] = "token #{ENV["GITHUB_TOKEN"]}" if ENV["GITHUB_TOKEN"] | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = uri.scheme === "https" | |
http.get(uri, headers) | |
end | |
def fetch_all_candidates(new, old) | |
page = 1 | |
found_new = false | |
found_old = false | |
candidates = [] | |
loop do | |
uri = URI.parse("https://api.github.com/repos/swiftwasm/swift/releases?page=#{page}&per_page=30") | |
response = github_get_response(uri) | |
abort "bad response code #{response.code}" unless response.code == "200" | |
releases = JSON.parse(response.body) | |
releases.each do |release| | |
next unless release["tag_name"].start_with?("swift-wasm-DEVELOPMENT-SNAPSHOT") | |
found_new ||= release["tag_name"] == new | |
found_old ||= release["tag_name"] == old | |
candidates.push(release) if found_new && !found_old | |
end | |
page += 1 | |
break if found_new and found_old | |
end | |
candidates | |
end | |
require "optparse" | |
opts = OptionParser.new | |
workdir = nil | |
opts.on("--workdir DIR") { |v| workdir = v } | |
opts.parse!(ARGV) | |
workdir ||= Dir.mktmpdir("toolchain-bisect") | |
bad_date = ARGV[0] | |
good_date = ARGV[1] | |
cmd = ARGV[2] | |
unless File.exist?(".cache-candidates.json") | |
candidates = fetch_all_candidates(good_date, bad_date) | |
File.write(".cache-candidates.json", JSON.dump(candidates)) | |
else | |
candidates = JSON.parse(File.read(".cache-candidates.json")) | |
end | |
oldest_bad = bisect_date_seq(candidates) do |candidate| | |
dir = fetch_snapshot(candidate["tag_name"], workdir) | |
new_bin_path = "#{dir}/usr/bin" | |
puts "Adding #{new_bin_path}, then testing..." if $VERBOSE | |
ok = system({"PATH" => "#{new_bin_path}#{File::PATH_SEPARATOR}#{ENV['PATH']}"}, cmd, chdir: dir) | |
puts "#{candidate["tag_name"]} is #{ok ? "good" : "bad"}" | |
ok | |
end | |
puts "#{oldest_bad["tag_name"]} is the oldest bad snapshot" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment