Move @k8slens/generate-tray-icons to seperate package (#7057)

* Move @k8slens/generate-tray-icons to seperate package

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Rename very long folder name to fix issue on windows

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Make it possible to build on windows using powershell

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix integration tests on windows

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Don't error on close directly

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Switch to type: module for generate-tray-icons

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Make more packages type:module

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix scripts needing node

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2023-02-01 11:41:44 -08:00
1 parent 89b2aab75d
commit b19e355e0e
90 files changed
+2872 -8119

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
dist/
node_modules/
+38
View File
@@ -0,0 +1,38 @@
{
"name": "@k8slens/generate-tray-icons",
"version": "6.4.0-beta.10",
"description": "CLI generating tray icons for building a lens-like application",
"license": "MIT",
"scripts": {
"clean": "rimraf dist/",
"build": "swc ./src/index.ts -d ./dist/",
"prepare:dev": "npm run build",
"prepare": "npm run build"
},
"bin": {
"generate-tray-icons": "./dist/index.js"
},
"files": [
"dist"
],
"type": "module",
"private": false,
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.30",
"@types/jsdom": "^20.0.1",
"@types/node": "^18.11.18",
"@types/sharp": "^0.31.1",
"rimraf": "^4.1.2"
},
"dependencies": {
"arg": "^5.0.2",
"jsdom": "^21.1.0",
"rimraf": "^4.1.2",
"sharp": "^0.31.3"
}
}
+155
View File
@@ -0,0 +1,155 @@
#!/usr/bin/env node
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { mkdir, readFile } from "fs/promises";
import { JSDOM } from "jsdom";
import path from "path";
import sharp from "sharp";
import arg from "arg";
const options = arg({
"--input": String,
"--output": String,
"--notice-icon": String,
"--spinner-icon": String,
"--output-size": Number,
});
type Options = typeof options;
const assertOption = <Key extends keyof Options>(key: Key): NonNullable<Options[Key]> => {
const raw = options[key];
if (!raw) {
console.error(`missing ${key} option`);
process.exit(1);
}
return raw;
};
const size = options["--output-size"] ?? 16;
const inputFile = assertOption("--input");
const outputFolder = assertOption("--output");
const noticeFile = assertOption("--notice-icon");
const spinnerFile = assertOption("--spinner-icon");
const getSvgStyling = (colouring: "dark" | "light") => (
`
<style>
ellipse {
stroke: ${colouring === "dark" ? "white" : "black"} !important;
}
path, rect {
fill: ${colouring === "dark" ? "white" : "black"} !important;
}
</style>
`
);
type TargetSystems = "macos" | "windows-or-linux";
const getBaseIconImage = async (system: TargetSystems) => {
const svgData = await readFile(inputFile, { encoding: "utf-8" });
const dom = new JSDOM(`<body>${svgData}</body>`);
const root = dom.window.document.body.getElementsByTagName("svg")[0];
root.innerHTML += getSvgStyling(system === "macos" ? "light" : "dark");
return Buffer.from(root.outerHTML);
}
const generateImage = (image: Buffer, size: number, namePrefix: string) => (
sharp(image)
.resize({ width: size, height: size })
.png()
.toFile(path.join(outputFolder, `${namePrefix}.png`))
);
const generateImages = (image: Buffer, size: number, name: string) => Promise.all([
generateImage(image, size, name),
generateImage(image, size * 2, `${name}@2x`),
generateImage(image, size * 3, `${name}@3x`),
generateImage(image, size * 4, `${name}@4x`),
]);
async function generateImageWithSvg(baseImage: Buffer, system: TargetSystems, filePath: string) {
const svgFile = await getIconImage(system, filePath);
const circleBuffer = await sharp(Buffer.from(`
<svg viewBox="0 0 64 64">
<circle cx="32" cy="32" r="32" fill="black" />
</svg>
`))
.toBuffer();
return sharp(baseImage)
.resize({ width: 128, height: 128 })
.composite([
{
input: circleBuffer,
top: 64,
left: 64,
blend: "dest-out",
},
{
input: (
await sharp(svgFile)
.resize({
width: 60,
height: 60,
})
.toBuffer()
),
top: 66,
left: 66,
},
])
.toBuffer();
}
async function getIconImage(system: TargetSystems, filePath: string) {
const svgData = await readFile(filePath, { encoding: "utf-8" });
const root = new JSDOM(svgData).window.document.getElementsByTagName("svg")[0];
root.innerHTML += getSvgStyling(system === "macos" ? "light" : "dark");
return Buffer.from(root.outerHTML);
}
try {
console.log("Generating tray icon pngs");
await mkdir(outputFolder, {
recursive: true,
});
const baseIconTemplateImage = await getBaseIconImage("macos");
const baseIconImage = await getBaseIconImage("windows-or-linux");
const updateAvailableTemplateImage = await generateImageWithSvg(baseIconTemplateImage, "macos", noticeFile);
const updateAvailableImage = await generateImageWithSvg(baseIconImage, "windows-or-linux", noticeFile);
const checkingForUpdatesTemplateImage = await generateImageWithSvg(baseIconTemplateImage, "macos", spinnerFile);
const checkingForUpdatesImage = await generateImageWithSvg(baseIconImage, "windows-or-linux", spinnerFile);
await Promise.all([
// Templates are for macOS only
generateImages(baseIconTemplateImage, size, "trayIconTemplate"),
generateImages(updateAvailableTemplateImage, size, "trayIconUpdateAvailableTemplate"),
generateImages(updateAvailableTemplateImage, size, "trayIconUpdateAvailableTemplate"),
generateImages(checkingForUpdatesTemplateImage, size, "trayIconCheckingForUpdatesTemplate"),
// Non-templates are for windows and linux
generateImages(baseIconImage, size, "trayIcon"),
generateImages(updateAvailableImage, size, "trayIconUpdateAvailable"),
generateImages(checkingForUpdatesImage, size, "trayIconCheckingForUpdates"),
]);
console.log("Generated all images");
} catch (error) {
console.error(error);
process.exit(1);
}
@@ -0,0 +1,19 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"outDir": "dist/",
"paths": {
"*": [
"node_modules/*",
"types/*"
]
},
},
"include": [
"src/**/*",
],
"exclude": [
"node_modules",
]
}
File diff suppressed because it is too large. Load diff