require 'git'
require 'net/http'
require 'fileutils'
BINDING_TARGETS = {
'java' => '//java/...',
'py' => '//py/...',
'rb' => '//rb/...',
'dotnet' => '//dotnet/...',
'javascript' => '//javascript/selenium-webdriver/...'
}.freeze
module SeleniumRake
BINDINGS = %w[ruby python javascript java dotnet].freeze
class << self
attr_accessor :git
end
def self.parse_tag(tag)
pattern = /^selenium-(\d+\.\d+\.\d+)(?:-(#{BINDINGS.join('|')}))?$/
match = tag&.match(pattern)
raise "Invalid tag format: #{tag}" unless match
version = match[1]
language = match[2] || 'all'
patch = version.split('.')[2].to_i
if patch.positive? && language == 'all'
raise "Patch releases must specify a language (e.g., selenium-#{version}-ruby)"
end
raise 'Full releases (X.Y.0) cannot have a language suffix' if patch.zero? && language != 'all'
{version: version, language: language, patch: patch}
end
def self.updated_version(current, desired = nil, nightly = nil)
if !desired.nil? && desired != 'nightly'
desired.split('.').tap { |v| v << 0 while v.size < 3 }.join('.')
elsif current.split(/\.|-/).size > 3
pattern = /-?\.?(nightly|SNAPSHOT|dev|\d{12})\d*$/
current.gsub(pattern, nightly)
elsif current.split(/\.|-/).size == 3
"#{current.split(/\.|-/).tap { |i| (i[1] = i[1].to_i + 1) && (i[2] = 0) }.join('.')}#{nightly}"
end
end
def self.previous_tag(current_version, language = nil)
version = current_version.split(/\.|-/)
if version.size > 3
puts 'WARNING - Changelogs not updated when set to prerelease'
elsif version[2].to_i > 1
patch_version = (version[2].to_i - 1).to_s
"selenium-#{[[version[0]], version[1], patch_version].join('.')}-#{language}"
elsif version[2] == '1'
"selenium-#{[[version[0]], version[1], '0'].join('.')}"
else
minor_version = (version[1].to_i - 1)
tags = git.tags.map(&:name)
tag = language ? tags.reverse.find { |t| t.match?(/selenium-4\.#{minor_version}.*-#{language}/) } : nil
tag || "selenium-#{[[version[0]], minor_version, '0'].join('.')}"
end
end
def self.update_changelog(version, language, path, changelog, header)
tag = previous_tag(version, language)
bullet = language == 'javascript' ? '-' : '*'
skip_patterns = /^(bump|update.*version|Bumping to nightly)/i
tags_to_remove = /\[(dotnet|rb|py|java|js|rust)\]:?\s?/
command = "git log #{tag}...HEAD --pretty=format:'%s' --reverse -- #{path}"
log = `#{command}`
entries = log.lines
.map(&:strip)
.grep(/\(#\d+\)/)
.grep_v(skip_patterns)
.map { |line| line.gsub(tags_to_remove, '') }
.map { |line| "#{bullet} #{line}" }
.join("\n")
content = File.read(changelog)
File.write(changelog, "#{header}\n#{entries}\n\n#{content}")
end
def self.verify_package_published(url)
puts "Verifying #{url}..."
uri = URI(url)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(Net::HTTP::Get.new(uri)) }
raise "Package not published: #{url}" unless res.is_a?(Net::HTTPSuccess)
puts 'Verified!'
end
end