#!/usr/bin/env -S docker run --rm -v ${PWD}/scripts:/scripts -v ${PWD}/.github/workflows:/.github/workflows dlanguage/dmd dmd -run /scripts/generate_badges.d // To run this script: // cd /path/to/cpu_features // ./scripts/generate_badges.d import std.algorithm : each, map, cartesianProduct, filter, joiner, sort, uniq; import std.array; import std.base64 : Base64; import std.conv : to; import std.file : exists; import std.format; import std.range : chain, only; import std.stdio; import std.string : representation; import std.traits : EnumMembers; immutable string bazel_svg = ``; const string bazel_svg_base64 = Base64.encode(representation(bazel_svg)); enum BuildSystem { CMake, Bazel } enum Cpu { amd64, AArch64, ARM, MIPS, POWER, RISCV, LOONGARCH, s390x, } enum Os { Linux, FreeBSD, MacOS, Windows, } struct Badge { const: Cpu cpu; Os os; BuildSystem build_system; private: string id() { return format("%d%c%d", cast(uint)(os) + 1, cast(char)('a' + cpu), cast(uint)(build_system)); } string link_ref() { return format("[l%s]", id()); } string image_ref() { return format("[i%s]", id()); } string filename() { import std.uni : toLower; return toLower(format("%s_%s_%s.yml", cpu, os, build_system)); } bool enabled() { return exists("../.github/workflows/" ~ filename()); } string append_logo(string url) { final switch (build_system) { case BuildSystem.CMake: return url ~ "&logo=cmake"; case BuildSystem.Bazel: return url ~ "&logo=data:image/svg%2bxml;base64," ~ bazel_svg_base64; } } public: string disabled_image_ref() { return format("[d%d]", cast(uint)(build_system)); } string text() { if (enabled()) return format("[![%s]%s]%s", build_system, image_ref, link_ref); return format("![%s]%s", build_system, disabled_image_ref); } string disabled_image_link() { return append_logo(format("%s: https://img.shields.io/badge/n%%2Fa-lightgrey?", disabled_image_ref)); } string link_decl() { return format("%s: https://github.com/google/cpu_features/actions/workflows/%s", link_ref, filename()); } string image_decl() { return append_logo(format("%s: https://img.shields.io/github/actions/workflow/status/google/cpu_features/%s?branch=main&event=push&label=", image_ref, filename())); } } auto tableHeader(in Os[] oses) { return chain(only(""), oses.map!(to!string)).array; } auto tableAlignment(in Os[] oses) { return chain(only(":--"), oses.map!(v => "--:")).array; } auto tableCell(Range)(in Os os, in Cpu cpu, Range badges) { return badges.filter!(b => b.cpu == cpu && b.os == os) .map!(b => b.text()) .joiner("
").to!string; } auto tableRow(Range)(in Cpu cpu, in Os[] oses, Range badges) { return chain(only(cpu.to!string), oses.map!(os => tableCell(os, cpu, badges))).array; } auto tableRows(Range)(in Os[] oses, in Cpu[] cpus, Range badges) { return cpus.map!(cpu => tableRow(cpu, oses, badges)).array; } auto table(Range)(in Os[] oses, in Cpu[] cpus, Range badges) { return chain(only(tableHeader(oses)), only(tableAlignment(oses)), tableRows(oses, cpus, badges)); } void main() { immutable allCpus = [EnumMembers!Cpu]; immutable allOses = [EnumMembers!Os]; immutable allBuildSystems = [EnumMembers!BuildSystem]; auto badges = cartesianProduct(allCpus, allOses, allBuildSystems).map!( t => Badge(t[0], t[1], t[2])); writefln("%(|%-( %s |%) |\n%) |", table(allOses, allCpus, badges)); writeln(); badges.filter!(b => !b.enabled) .map!(b => b.disabled_image_link()) .array .sort .uniq .each!writeln; badges.filter!(b => b.enabled) .map!(b => [b.link_decl(), b.image_decl()]) .joiner().array.sort.uniq.each!writeln; }