1//! Run this with `zig build gen`
2
3const std = @import("std");
4const json = @import("json");
5const nfs = @import("nfs");
6
7pub fn main() !void {
8 var gpa = std.heap.DebugAllocator(.{}){};
9 const alloc = gpa.allocator();
10
11 const f = try nfs.cwd().createFile("src/lib.zig", .{});
12 const w = f;
13
14 {
15 std.log.info("spdx", .{});
16 const doc = try simple_fetch(alloc, "https://raw.githubusercontent.com/spdx/license-list-data/master/json/licenses.json");
17 defer doc.deinit(alloc);
18 const val = doc.root.object();
19
20 try w.writeAll("// SPDX License Data generated from https://github.com/spdx/license-list-data\n");
21 try w.writeAll("//\n");
22 try w.print("// Last generated from version {s}\n", .{val.getS("licenseListVersion").?});
23 try w.writeAll("//\n");
24
25 const licenses = try mutdupe(alloc, json.ValueIndex, val.getA("licenses").?);
26 std.mem.sort(json.ValueIndex, licenses, {}, spdxlicenseLessThan);
27
28 try w.writeAll("\n");
29 try w.writeAll("pub const spdx = &[_][]const u8{\n");
30 for (licenses) |lic| {
31 try w.print(" \"{s}\",\n", .{
32 lic.object().getS("licenseId").?,
33 });
34 }
35 try w.writeAll("};\n");
36
37 try w.writeAll("\n");
38 try w.writeAll("pub const osi = &[_][]const u8{\n");
39 for (licenses) |lic| {
40 if (!lic.object().getB("isOsiApproved").?) continue;
41 try w.print(" \"{s}\",\n", .{lic.object().getS("licenseId").?});
42 }
43 try w.writeAll("};\n");
44 }
45
46 {
47 std.log.info("blueoak", .{});
48 const doc = try simple_fetch(alloc, "https://blueoakcouncil.org/list.json");
49 defer doc.deinit(alloc);
50 const val = doc.root.object();
51
52 try w.writeAll("\n");
53 try w.writeAll("// Blue Oak Council data generated from https://blueoakcouncil.org/list\n");
54 try w.writeAll("//\n");
55 try w.print("// Last generated from version {s}\n", .{val.getS("version").?});
56 try w.writeAll("//\n");
57
58 try w.writeAll("\n");
59 try w.writeAll("pub const blueoak = struct {\n");
60 for (val.getA("ratings").?) |rating| {
61 try w.print(" pub const {s} = &[_][]const u8{{\n", .{try std.ascii.allocLowerString(alloc, rating.object().getS("name").?)});
62 for (rating.object().getA("licenses").?) |lic| {
63 try w.print(" \"{s}\",\n", .{
64 lic.object().getS("id").?,
65 });
66 }
67 try w.print(" }};\n", .{});
68 }
69 try w.writeAll("};\n");
70 }
71}
72
73pub fn simple_fetch(alloc: std.mem.Allocator, url: []const u8) !json.Document {
74 const io = std.Options.debug_io;
75 var client = std.http.Client{ .allocator = alloc, .io = io };
76 defer client.deinit();
77
78 var list = std.Io.Writer.Allocating.init(alloc);
79 defer list.deinit();
80
81 const fetch = try client.fetch(.{
82 .location = .{ .url = url },
83 .response_writer = &list.writer,
84 });
85 const opts = json.Parser.Options{ .maximum_depth = 100, .support_trailing_commas = true };
86 if (fetch.status != .ok) return try json.parseFromSlice(alloc, url, "{}", opts);
87 return try json.parseFromSlice(alloc, url, list.written(), opts);
88}
89
90fn spdxlicenseLessThan(context: void, lhs: json.ValueIndex, rhs: json.ValueIndex) bool {
91 _ = context;
92 const l = lhs.object().getS("licenseId").?;
93 const r = rhs.object().getS("licenseId").?;
94 return std.mem.lessThan(u8, l, r);
95}
96
97fn mutdupe(alloc: std.mem.Allocator, comptime T: type, original: anytype) ![]T {
98 const slice = try alloc.alloc(T, original.len);
99 for (original, 0..) |item, i| slice[i] = item;
100 return slice;
101}