1 import std.algorithm : each, map, cartesianProduct, filter, joiner, sort, uniq;
2 import std.array : array;
3 import std.conv : to;
4 import std.format;
5 import std.range : chain, only;
6 import std.stdio;
7 import std.traits : EnumMembers;
8
9 enum BuildSystem
10 {
11 CMake,
12 Bazel
13 }
14
15 enum Cpu
16 {
17 amd64,
18 AArch64,
19 ARM,
20 MIPS,
21 POWER,
22 RISCV,
23 s390x,
24 }
25
26 enum Os
27 {
28 Linux,
29 FreeBSD,
30 MacOS,
31 Windows,
32 }
33
34 struct Badge
35 {
36 const:
37
38 Cpu cpu;
39 Os os;
40 BuildSystem build_system;
41
id()42 string id()
43 {
44 return format("%d%c%d", cast(uint)(os) + 1, cast(char)('a' + cpu), cast(uint)(build_system));
45 }
46
disabled_image_ref()47 string disabled_image_ref()
48 {
49 return format("[d%d]", cast(uint)(build_system));
50 }
51
link_ref()52 string link_ref()
53 {
54 return format("[l%s]", id());
55 }
56
image_ref()57 string image_ref()
58 {
59 return format("[i%s]", id());
60 }
61
enabled()62 bool enabled()
63 {
64 final switch (build_system)
65 {
66 case BuildSystem.CMake:
67 return os == Os.Linux || cpu == Cpu.amd64;
68 case BuildSystem.Bazel:
69 return os == Os.Linux && cpu == Cpu.amd64;
70 }
71 }
72
text()73 string text()
74 {
75 if (enabled())
76 return format("[![]%s]%s", image_ref, link_ref);
77 return format("![]%s", disabled_image_ref);
78 }
79
disabled_image_link()80 string disabled_image_link()
81 {
82 return format("%s: https://img.shields.io/badge/%s-N%%2FA-lightgrey", disabled_image_ref, build_system);
83 }
84
filename()85 string filename()
86 {
87 import std.uni : toLower;
88
89 return toLower(format("%s_%s_%s.yml", cpu, os, build_system));
90 }
91
link_decl()92 string link_decl()
93 {
94 return format("%s: https://github.com/google/cpu_features/actions/workflows/%s", link_ref, filename());
95 }
96
image_decl()97 string image_decl()
98 {
99 return format(
100 "%s: https://img.shields.io/github/actions/workflow/status/google/cpu_features/%s?branch=main&label=%s", image_ref, filename(), build_system);
101 }
102 }
103
tableHeader(in Cpu[]cpus)104 auto tableHeader(in Cpu[] cpus)
105 {
106 return chain(only("Os"), cpus.map!(to!string)).array;
107 }
108
tableAlignment(in Cpu[]cpus)109 auto tableAlignment(in Cpu[] cpus)
110 {
111 return chain(only(":--"), cpus.map!(v => "--:")).array;
112 }
113
tableCell(Range)114 auto tableCell(Range)(in Os os, in Cpu cpu, Range badges)
115 {
116 return badges
117 .filter!(b => b.cpu == cpu && b.os == os)
118 .map!(b => b.text())
119 .joiner("<br/>")
120 .to!string;
121 }
122
tableRow(Range)123 auto tableRow(Range)(in Os os, in Cpu[] cpus, Range badges)
124 {
125 return chain(only(os.to!string), cpus.map!(cpu => tableCell(os, cpu, badges))).array;
126 }
127
tableRows(Range)128 auto tableRows(Range)(in Os[] oses, in Cpu[] cpus, Range badges)
129 {
130 return oses.map!(os => tableRow(os, cpus, badges)).array;
131 }
132
table(Range)133 auto table(Range)(in Os[] oses, in Cpu[] cpus, Range badges)
134 {
135 return chain(only(tableHeader(cpus)), only(tableAlignment(cpus)), tableRows(oses, cpus, badges));
136 }
137
main()138 void main()
139 {
140 immutable allCpus = [EnumMembers!Cpu];
141 immutable allOses = [EnumMembers!Os];
142 immutable allBuildSystems = [EnumMembers!BuildSystem];
143
144 auto badges = cartesianProduct(allCpus, allOses, allBuildSystems).map!(
145 t => Badge(t[0], t[1], t[2]));
146
147 writefln("%(|%-( %s |%) |\n%) |", table(allOses, allCpus, badges));
148 writeln();
149 badges
150 .filter!(b => !b.enabled)
151 .map!(b => b.disabled_image_link())
152 .array
153 .sort
154 .uniq
155 .each!writeln;
156
157 badges
158 .filter!(b => b.enabled)
159 .map!(b => [b.link_decl(), b.image_decl()])
160 .joiner()
161 .array
162 .sort
163 .uniq
164 .each!writeln;
165 }
166