"use strict"; const path = require("path"); const fs = require("fs-extra"); const semver = require("semver"); const execMain = require("../shared/execMain"); const ChangeFileDir = path.join(__dirname, "../../changes"); const Version = process.argv[2]; const releasePackagesJsonPath = process.argv[3]; const outputPath = process.argv[4]; execMain(main); /////////////////////////////////////////////////////////////////////////////////////////////////// async function main() { const out = new Output(); await GenerateChangeList(out); await CopyMarkdown(out, "packages-desc.md"); await GeneratePackageList(out); await fs.ensureDir(path.join(__dirname, `../../release-archives/`)); await fs.writeFile(outputPath, out.buffer); } class Output { constructor() { this.buffer = ""; } log(...s) { this.buffer += s.join("") + "\n"; } } /////////////////////////////////////////////////////////////////////////////////////////////////// // Copy Markdown async function CopyMarkdown(out, name) { const content = await fs.readFile( path.resolve(__dirname, `release-note-fragments/${name}`), "utf8" ); out.log(content); } /////////////////////////////////////////////////////////////////////////////////////////////////// // CHANGE LIST async function GenerateChangeList(out) { const changeFiles = await fs.readdir(ChangeFileDir); const fragments = new Map(); for (const file of changeFiles) { const filePath = path.join(ChangeFileDir, file); const fileParts = path.parse(filePath); if (fileParts.ext !== ".md") continue; if (!semver.valid(fileParts.name) || semver.lt(Version, fileParts.name)) continue; fragments.set(fileParts.name, await fs.readFile(filePath, "utf8")); } const sortedFragments = Array.from(fragments).sort((a, b) => semver.compare(b[0], a[0])); const [version, notes] = sortedFragments[0]; out.log(``); out.log(`## Changes of version ${version}`); out.log(notes.trimEnd() + "\n"); } /////////////////////////////////////////////////////////////////////////////////////////////////// // PACKAGE LIST const Spacings = { // spacingDesc, ligation, spacingNameSuffix type: ["Default", true], term: ["Terminal", true], fixed: ["Fixed", false] }; const imagePrefix = `https://raw.githubusercontent.com/be5invis/Iosevka/v${Version}/images`; async function GeneratePackageList(out) { const pkgShapesData = await fs.readJson(releasePackagesJsonPath); out.log(``); for (let [groupID, gr] of Object.entries(pkgShapesData)) { const prime = gr.subGroups[groupID]; const familyName = buildName("\u00a0", ...prime.family.split(" ")); const fileName = buildName("-", "ttc", groupID, Version); const downloadLink = `https://github.com/be5invis/Iosevka/releases/download/v${Version}/${fileName}.zip`; const proportionPrefix = gr.quasiProportional ? "Quasi-proportional" : "Monospace"; const desc = `${proportionPrefix}, ${prime.desc}`; const img = ``; out.log( ``, ``, ``, `` ); out.log( ``, ``, ``, ``, ``, `` ); let lastSubGroupID = null; for (const [subGroupID, subGr] of Object.entries(gr.subGroups)) { lastSubGroupID = subGroupID; } for (const [subGroupID, subGr] of Object.entries(gr.subGroups)) { const [spacingDesc, ligation] = Spacings[subGr.spacing]; const createLink = (label, prefix) => { const fileName = buildName("-", prefix, subGroupID, Version); const downloadLink = `https://github.com/be5invis/Iosevka/releases/download/v${Version}/${fileName}.zip`; return `${label}`; }; const leader = "    " + (subGroupID === lastSubGroupID ? "└" : "├"); out.log( ``, ``, ``, ``, ``, ``, ``, `` ); } out.log(``, ``, ``); } out.log(`
📦 ${familyName} — ${desc}TTC
  └ Sub-packagesSpacingLigaturesDownloads
${leader} ${noBreak(subGr.family)}${spacingDesc}${flag(ligation)}${createLink("TTF", "ttf")}${createLink("Unhinted", "ttf-unhinted")}${createLink("WebFont", "webfont")}
${img}
\n`); } function noBreak(s) { return s.replace(/ /g, "\u00a0"); } function buildName(j, ...parts) { return parts.filter(x => !!x).join(j); } function flag(f) { return f ? "Yes" : "No"; }