require 'yaml' require 'date' require 'json' require 'rugged' require 'liquid' WEBSITE_DIR = ARGV[0] CACHE_DIR = ARGV[1] OUTPUT_DIR = ARGV[2] OPTIONAL_PRODUCT = ARGV[3] # This regex is used in absence of anything else # This is more lenient from semver, but disallows MAJOR=0 as well # It also allows MAJOR.MINOR, which is quite common DEFAULT_VERSION_REGEX = '^v?(?[1-9]\d*)\.(?0|[1-9]\d*)\.?(?0|[1-9]\d*)?$' DEFAULT_TAG_TEMPLATE = '{{major}}.{{minor}}{% if patch %}.{{patch}}{%endif%}' def fetch_git_releases(repo_dir, url) pwd = Dir.pwd puts "Fetching #{url}" `git init --bare #{repo_dir}` unless Dir.exist? repo_dir Dir.chdir repo_dir `git fetch --quiet --tags --filter=blob:none "#{url}"` Dir.chdir pwd end def good_tag(tag, config) config['regex'] ||= DEFAULT_VERSION_REGEX tag.match?(config['regex']) end def render_tag(tag, config) config['regex'] ||= DEFAULT_SEMVER_REGEX data = tag.match(config['regex']).named_captures template = config['template'] ? config['template'] : DEFAULT_TAG_TEMPLATE Liquid::Template.parse(template).render(data) end def update_git_releases(repo_dir, output_file, auto_config) data = {} repo = Rugged::Repository.bare repo_dir repo.tags.each do |tag| next unless good_tag(tag.name, auto_config) tag_proper_name = render_tag(tag.name, auto_config) if tag.target.is_a? Rugged::Tag::Annotation data[tag_proper_name] = tag.target.tagger[:time].strftime('%F') else begin data[tag_proper_name] = tag.target.time.strftime('%F') rescue StandardError puts "[WARN] No timestamp for #{tag.name}" end end end File.open(output_file, 'w') do |file| file.write(JSON.pretty_generate(data)) end end def get_cache_dir(ecosystem, product) "#{CACHE_DIR}/#{ecosystem}/#{product}" end def get_output_file(ecosystem, product) "#{OUTPUT_DIR}/#{ecosystem}/#{product}.json" end Dir.glob("#{WEBSITE_DIR}/products/*.md").each do |product_file| data = YAML.safe_load_file product_file, permitted_classes: [Date] next unless data['auto'] product = File.basename product_file, '.md' next if OPTIONAL_PRODUCT && (OPTIONAL_PRODUCT != product) if data['auto']['git'] fetch_git_releases(get_cache_dir('git', product), data['auto']['git']) update_git_releases(get_cache_dir('git', product), get_output_file('git', product), data['auto']) end end