buildLicenses.ts

 1import * as fs from "fs"
 2import toml from "toml"
 3import { schemeMeta } from "./colorSchemes"
 4import { Meta } from "./themes/common/colorScheme"
 5import https from "https"
 6import crypto from "crypto"
 7
 8const accepted_licenses_file = `${__dirname}/../../script/licenses/zed-licenses.toml`
 9
10// Use the cargo-about configuration file as the source of truth for supported licenses.
11function parseAcceptedToml(file: string): string[] {
12    let buffer = fs.readFileSync(file).toString()
13
14    let obj = toml.parse(buffer)
15
16    if (!Array.isArray(obj.accepted)) {
17        throw Error("Accepted license source is malformed")
18    }
19
20    return obj.accepted
21}
22
23function checkLicenses(schemeMeta: Meta[], licenses: string[]) {
24    for (let meta of schemeMeta) {
25        // FIXME: Add support for conjuctions and conditions
26        if (licenses.indexOf(meta.license.SPDX) < 0) {
27            throw Error(
28                `License for theme ${meta.name} (${meta.license.SPDX}) is not supported`
29            )
30        }
31    }
32}
33
34function getLicenseText(
35    schemeMeta: Meta[],
36    callback: (meta: Meta, license_text: string) => void
37) {
38    for (let meta of schemeMeta) {
39        // The following copied from the example code on nodejs.org:
40        // https://nodejs.org/api/http.html#httpgetoptions-callback
41        https
42            .get(meta.license.https_url, (res) => {
43                const { statusCode } = res
44
45                if (statusCode < 200 || statusCode >= 300) {
46                    throw new Error(
47                        `Failed to fetch license for: ${meta.name}, Status Code: ${statusCode}`
48                    )
49                }
50
51                res.setEncoding("utf8")
52                let rawData = ""
53                res.on("data", (chunk) => {
54                    rawData += chunk
55                })
56                res.on("end", () => {
57                    const hash = crypto
58                        .createHash("sha256")
59                        .update(rawData)
60                        .digest("hex")
61                    if (meta.license.license_checksum == hash) {
62                        callback(meta, rawData)
63                    } else {
64                        throw Error(
65                            `Checksum for ${meta.name} did not match file downloaded from ${meta.license.https_url}`
66                        )
67                    }
68                })
69            })
70            .on("error", (e) => {
71                throw e
72            })
73    }
74}
75
76function writeLicense(schemeMeta: Meta, text: String) {
77    process.stdout.write(
78        `## [${schemeMeta.name}](${schemeMeta.url})\n\n${text}\n********************************************************************************\n\n`
79    )
80}
81
82const accepted_licenses = parseAcceptedToml(accepted_licenses_file)
83checkLicenses(schemeMeta, accepted_licenses)
84
85getLicenseText(schemeMeta, (meta, text) => {
86    writeLicense(meta, text)
87})