buildLicenses.ts

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