|
| 1 | +#!/usr/bin/env ruby |
| 2 | +# |
| 3 | +# Licensed to the Apache Software Foundation (ASF) under one |
| 4 | +# or more contributor license agreements. See the NOTICE file |
| 5 | +# distributed with this work for additional information |
| 6 | +# regarding copyright ownership. The ASF licenses this file |
| 7 | +# to you under the Apache License, Version 2.0 (the |
| 8 | +# "License"); you may not use this file except in compliance |
| 9 | +# with the License. You may obtain a copy of the License at |
| 10 | +# |
| 11 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | +# |
| 13 | +# Unless required by applicable law or agreed to in writing, |
| 14 | +# software distributed under the License is distributed on an |
| 15 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 16 | +# KIND, either express or implied. See the License for the |
| 17 | +# specific language governing permissions and limitations |
| 18 | +# under the License. |
| 19 | + |
| 20 | +require "digest/sha2" |
| 21 | +require "json" |
| 22 | +require "open-uri" |
| 23 | + |
| 24 | +if ARGV.empty? |
| 25 | + puts("Usage: #{$0} PRODUCT_PATTERN1 PRODUCT_PATTERN2 ...") |
| 26 | + puts(" e.g.: #{$0} 'AWS*' 'S2N*'.") |
| 27 | + exit(false) |
| 28 | +end |
| 29 | + |
| 30 | +def parse_versions_txt_content(content) |
| 31 | + products = {} |
| 32 | + content.each_line(chomp: true) do |line| |
| 33 | + case line |
| 34 | + when /\AARROW_([A-Za-z0-9_-]+)_BUILD_VERSION=(.+?)\z/ |
| 35 | + product = Regexp.last_match[1] |
| 36 | + version = Regexp.last_match[2] |
| 37 | + products[product] = {version: version} |
| 38 | + when /\AARROW_([A-Za-z0-9_-]+)_BUILD_SHA256_CHECKSUM=(.+?)\z/ |
| 39 | + product = Regexp.last_match[1] |
| 40 | + checksum = Regexp.last_match[2] |
| 41 | + products[product][:checksum] = checksum |
| 42 | + when /\A "ARROW_([A-Za-z0-9_-]+)_URL (?:\S+) (\S+)"\z/ |
| 43 | + product = Regexp.last_match[1] |
| 44 | + url_template = Regexp.last_match[2] |
| 45 | + url_template.gsub!(/\${.+?}/) do |matched| |
| 46 | + if matched.end_with?("//./_}") |
| 47 | + "%{version_underscore}" |
| 48 | + else |
| 49 | + "%{version}" |
| 50 | + end |
| 51 | + end |
| 52 | + products[product][:url_template] = url_template |
| 53 | + end |
| 54 | + end |
| 55 | + products |
| 56 | +end |
| 57 | + |
| 58 | +def update_product_github(product, metadata, repository) |
| 59 | + version = metadata[:version] |
| 60 | + tags_url = "https://api.github.com/repos/#{repository}/tags" |
| 61 | + tags = URI.open(tags_url) do |response| |
| 62 | + JSON.parse(response.read) |
| 63 | + end |
| 64 | + latest_tag_name = tags[0]["name"] |
| 65 | + if latest_tag_name.start_with?("v") |
| 66 | + if metadata[:version].start_with?("v") |
| 67 | + latest_version = latest_tag_name |
| 68 | + else |
| 69 | + latest_version = latest_tag_name[1..-1] |
| 70 | + end |
| 71 | + else |
| 72 | + latest_version = latest_tag_name |
| 73 | + end |
| 74 | + return if version == latest_version |
| 75 | + |
| 76 | + url_template = metadata[:url_template] |
| 77 | + url = url_template % { |
| 78 | + version: latest_version, |
| 79 | + version_underscore: latest_version.gsub(".", "_"), |
| 80 | + } |
| 81 | + $stderr.puts("Updating #{product}: #{version} -> #{latest_version}") |
| 82 | + metadata[:version] = latest_version |
| 83 | + URI.open(url, "rb") do |response| |
| 84 | + metadata[:checksum] = Digest::SHA256.hexdigest(response.read) |
| 85 | + end |
| 86 | + $stderr.puts(" Checksum: #{metadata[:checksum]}") |
| 87 | +end |
| 88 | + |
| 89 | +def update_product(product, metadata) |
| 90 | + url_template = metadata[:url_template] |
| 91 | + if url_template.nil? |
| 92 | + $stderr.puts("#{product} isn't supported " + |
| 93 | + "because there is no associated URL") |
| 94 | + return |
| 95 | + end |
| 96 | + |
| 97 | + case url_template |
| 98 | + when /\Ahttps:\/\/github.com\/((?:[^\/]+)\/(?:[^\/]+))\// |
| 99 | + github_repository = Regexp.last_match[1] |
| 100 | + update_product_github(product, metadata, github_repository) |
| 101 | + else |
| 102 | + $stderr.puts("TODO: #{product} isn't supported yet: #{url_template}") |
| 103 | + end |
| 104 | +end |
| 105 | + |
| 106 | +def update_versions_txt_content!(content, products) |
| 107 | + products.each do |product, metadata| |
| 108 | + prefix = "ARROW_#{Regexp.escape(product)}" |
| 109 | + content.gsub!(/^#{prefix}_BUILD_VERSION=.*$/) do |
| 110 | + "ARROW_#{product}_BUILD_VERSION=#{metadata[:version]}" |
| 111 | + end |
| 112 | + content.gsub!(/^#{prefix}_BUILD_SHA256_CHECKSUM=.*?$/) do |
| 113 | + "ARROW_#{product}_BUILD_SHA256_CHECKSUM=#{metadata[:checksum]}" |
| 114 | + end |
| 115 | + end |
| 116 | +end |
| 117 | + |
| 118 | +versions_txt = File.join(__dir__, "versions.txt") |
| 119 | +versions_txt_content = File.read(versions_txt) |
| 120 | +products = parse_versions_txt_content(versions_txt_content) |
| 121 | +ARGV.each do |pattern| |
| 122 | + target_products = products.filter do |product, _| |
| 123 | + File.fnmatch?(pattern, product) |
| 124 | + end |
| 125 | + target_products.each do |product, metadata| |
| 126 | + update_product(product, metadata) |
| 127 | + end |
| 128 | +end |
| 129 | +update_versions_txt_content!(versions_txt_content, products) |
| 130 | +File.write(versions_txt, versions_txt_content) |
0 commit comments