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

+3 -1
View File
@@ -1,4 +1,6 @@
static/build
binaries/
dist/
node_modules/
node_modules/
*.mjs
*.mjs.map
@@ -1,139 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { ensureDir, readFile } from "fs-extra";
import { JSDOM } from "jsdom";
import path from "path";
import sharp from "sharp";
const size = Number(process.env.OUTPUT_SIZE || "16");
const outputFolder = process.env.OUTPUT_DIR || "./static/build/tray";
const inputFile = process.env.INPUT_SVG_PATH || path.resolve(__dirname, "../../core/src/renderer/components/icon/logo-lens.svg");
const noticeFile = process.env.NOTICE_SVG_PATH || path.resolve(__dirname, "../../core/src/renderer/components/icon/notice.svg");
const spinnerFile = process.env.SPINNER_SVG_PATH || path.resolve(__dirname, "../../core/src/renderer/components/icon/arrow-spinner.svg");
async function ensureOutputFoler() {
await ensureDir(outputFolder);
}
function getSvgStyling(colouring: "dark" | "light"): string {
return `
<style>
ellipse {
stroke: ${colouring === "dark" ? "white" : "black"} !important;
}
path, rect {
fill: ${colouring === "dark" ? "white" : "black"} !important;
}
</style>
`;
}
type TargetSystems = "macos" | "windows-or-linux";
async function getBaseIconImage(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);
}
async function generateImage(image: Buffer, size: number, namePrefix: string) {
sharp(image)
.resize({ width: size, height: size })
.png()
.toFile(path.join(outputFolder, `${namePrefix}.png`));
}
async function generateImages(image: Buffer, size: number, name: string) {
await 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);
}
async function generateTrayIcons() {
try {
console.log("Generating tray icon pngs");
await ensureOutputFoler();
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);
}
}
generateTrayIcons();
Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

-6
View File
@@ -1,6 +0,0 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*",
]
}
@@ -1,2 +0,0 @@
/*! For license information please see node-fetch.bundle.js.LICENSE.txt */
(()=>{var e={414:(e,t,r)=>{if(!globalThis.DOMException)try{const{MessageChannel:e}=r(267),t=(new e).port1,o=new ArrayBuffer;t.postMessage(o,[o,o])}catch(e){"DOMException"===e.constructor.name&&(globalThis.DOMException=e.constructor)}e.exports=globalThis.DOMException},660:function(e,t){var r;r=function(e){"use strict";const t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`;function r(){}const o="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;function n(e){return"object"==typeof e&&null!==e||"function"==typeof e}const i=r,s=Promise,a=Promise.prototype.then,l=Promise.resolve.bind(s),u=Promise.reject.bind(s);function c(e){return new s(e)}function d(e){return l(e)}function f(e){return u(e)}function h(e,t,r){return a.call(e,t,r)}function p(e,t,r){h(h(e,t,r),void 0,i)}function b(e,t){p(e,t)}function y(e,t){p(e,void 0,t)}function m(e,t,r){return h(e,t,r)}function _(e){h(e,void 0,i)}const g=(()=>{const e=o&&o.queueMicrotask;if("function"==typeof e)return e;const t=d(void 0);return e=>h(t,e)})();function w(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function v(e,t,r){try{return d(w(e,t,r))}catch(e){return f(e)}}class S{constructor(){this._cursor=0,this._size=0,this._front={_elements:[],_next:void 0},this._back=this._front,this._cursor=0,this._size=0}get length(){return this._size}push(e){const t=this._back;let r=t;16383===t._elements.length&&(r={_elements:[],_next:void 0}),t._elements.push(e),r!==t&&(this._back=r,t._next=r),++this._size}shift(){const e=this._front;let t=e;const r=this._cursor;let o=r+1;const n=e._elements,i=n[r];return 16384===o&&(t=e._next,o=0),--this._size,this._cursor=o,e!==t&&(this._front=t),n[r]=void 0,i}forEach(e){let t=this._cursor,r=this._front,o=r._elements;for(;!(t===o.length&&void 0===r._next||t===o.length&&(r=r._next,o=r._elements,t=0,0===o.length));)e(o[t]),++t}peek(){const e=this._front,t=this._cursor;return e._elements[t]}}function T(e,t){e._ownerReadableStream=t,t._reader=e,"readable"===t._state?A(e):"closed"===t._state?function(e){A(e),k(e)}(e):C(e,t._storedError)}function R(e,t){return wr(e._ownerReadableStream,t)}function E(e){"readable"===e._ownerReadableStream._state?q(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")):function(e,t){C(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness"))}(e),e._ownerReadableStream._reader=void 0,e._ownerReadableStream=void 0}function P(e){return new TypeError("Cannot "+e+" a stream using a released reader")}function A(e){e._closedPromise=c(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r}))}function C(e,t){A(e),q(e,t)}function q(e,t){void 0!==e._closedPromise_reject&&(_(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}function k(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}const O=t("[[AbortSteps]]"),B=t("[[ErrorSteps]]"),L=t("[[CancelSteps]]"),j=t("[[PullSteps]]"),z=Number.isFinite||function(e){return"number"==typeof e&&isFinite(e)},W=Math.trunc||function(e){return e<0?Math.ceil(e):Math.floor(e)};function $(e,t){if(void 0!==e&&"object"!=typeof(r=e)&&"function"!=typeof r)throw new TypeError(`${t} is not an object.`);var r}function F(e,t){if("function"!=typeof e)throw new TypeError(`${t} is not a function.`)}function D(e,t){if(!function(e){return"object"==typeof e&&null!==e||"function"==typeof e}(e))throw new TypeError(`${t} is not an object.`)}function M(e,t,r){if(void 0===e)throw new TypeError(`Parameter ${t} is required in '${r}'.`)}function x(e,t,r){if(void 0===e)throw new TypeError(`${t} is required in '${r}'.`)}function I(e){return Number(e)}function U(e){return 0===e?0:e}function H(e,t){const r=Number.MAX_SAFE_INTEGER;let o=Number(e);if(o=U(o),!z(o))throw new TypeError(`${t} is not a finite number`);if(o=function(e){return U(W(e))}(o),o<0||o>r)throw new TypeError(`${t} is outside the accepted range of 0 to ${r}, inclusive`);return z(o)&&0!==o?o:0}function N(e,t){if(!_r(e))throw new TypeError(`${t} is not a ReadableStream.`)}function V(e){return new J(e)}function Y(e,t){e._reader._readRequests.push(t)}function Q(e,t,r){const o=e._reader._readRequests.shift();r?o._closeSteps():o._chunkSteps(t)}function Z(e){return e._reader._readRequests.length}function G(e){const t=e._reader;return void 0!==t&&!!K(t)}class J{constructor(e){if(M(e,1,"ReadableStreamDefaultReader"),N(e,"First parameter"),gr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");T(this,e),this._readRequests=new S}get closed(){return K(this)?this._closedPromise:f(ee("closed"))}cancel(e){return K(this)?void 0===this._ownerReadableStream?f(P("cancel")):R(this,e):f(ee("cancel"))}read(){if(!K(this))return f(eLine truncated
@@ -1 +0,0 @@
/*! node-domexception. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
@@ -36,13 +36,8 @@ async function getMainWindow(app: ElectronApplication, timeout = 50_000): Promis
app.on("window", onWindow);
cleanup.push(() => app.off("window", onWindow));
const onClose = () => {
cleanup();
reject(new Error("App has unnexpectedly closed"));
};
app.on("close", onClose);
cleanup.push(() => app.off("close", onClose));
app.on("close", cleanup);
cleanup.push(() => app.off("close", cleanup));
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const stdout = app.process().stdout!;
@@ -86,7 +81,7 @@ async function attemptStart() {
app,
window,
cleanup: async () => {
await app.close();
app.process().kill();
await remove(CICD).catch(noop);
},
};
+7 -4
View File
@@ -34,7 +34,7 @@
"dev:main": "cross-env NODE_ENV=development webpack --config webpack/main.ts --progress --watch",
"dev:renderer": "cross-env NODE_ENV=development ts-node ./webpack/dev-server.ts",
"test:integration": "jest -xyz --runInBand --detectOpenHandles --forceExit --modulePaths=[\"<rootDir>/integration/\"];",
"build:tray-icons": "ts-node build/generate-tray-icons.ts",
"build:tray-icons": "generate-tray-icons --output ./static/build/tray --input ./node_modules/@k8slens/core/src/renderer/components/icon/logo-lens.svg --notice-icon ./node_modules/@k8slens/core/src/renderer/components/icon/notice.svg --spinner-icon ./node_modules/@k8slens/core/src/renderer/components/icon/arrow-spinner.svg",
"download:binaries": "ensure-binaries --package ./package.json --base-dir ./binaries/client"
},
"config": {
@@ -194,16 +194,19 @@
"dependencies": {
"@k8slens/core": "^6.4.0-beta.10",
"@k8slens/ensure-binaries": "^6.4.0-beta.10",
"@k8slens/generate-tray-icons": "^6.4.0-beta.10",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
"@ogre-tools/injectable-react": "^12.0.1",
"mobx": "^6.7.0"
"mobx": "^6.7.0",
"rimraf": "^4.1.2"
},
"devDependencies": {
"@k8slens/node-fetch": "^6.4.0-beta.10",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.31",
"@swc/jest": "^0.2.24",
"@types/byline": "^4.2.33",
@@ -230,6 +233,7 @@
"autoprefixer": "^10.4.13",
"circular-dependency-plugin": "^5.2.2",
"concurrently": "^7.6.0",
"cross-env": "^7.0.3",
"css-loader": "^6.7.2",
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
@@ -239,7 +243,6 @@
"html-webpack-plugin": "^5.5.0",
"jest": "^28.1.3",
"jest-environment-jsdom": "^28.1.3",
"jsdom": "^20.0.3",
"jsonfile": "^6.1.0",
"mini-css-extract-plugin": "^2.7.1",
"monaco-editor": "^0.29.1",
@@ -250,8 +253,8 @@
"react-refresh": "^0.14.0",
"react-refresh-typescript": "^2.0.7",
"react-select": "^5.7.0",
"rimraf": "^4.1.2",
"run-script-os": "^1.1.6",
"sharp": "^0.31.2",
"style-loader": "^3.3.1",
"tailwindcss": "^3.2.4",
"ts-loader": "^9.4.2",
+7 -8
View File
@@ -15,7 +15,7 @@
import { DefinePlugin } from "webpack";
import { assetsFolderName, isDevelopment, rendererDir, buildDir, htmlTemplate, publicPath, sassCommonVars } from "./vars";
import { platform } from "process";
const renderer: webpack.Configuration = {
target: "electron-renderer",
name: "lens-app-renderer",
@@ -120,7 +120,7 @@
),
],
};
/**
* Import icons and image files.
* Read more about asset types: https://webpack.js.org/guides/asset-modules/
@@ -137,7 +137,7 @@
},
];
}
/**
* Import custom fonts as URL.
*/
@@ -149,11 +149,11 @@
},
];
}
export interface CssModulesWebpackRuleOptions {
styleLoader?: string;
}
/**
* Import CSS or SASS styles with modules support (*.module.scss)
*/
@@ -161,7 +161,7 @@
styleLoader ??= isDevelopment
? "style-loader"
: MiniCssExtractPlugin.loader;
return {
test: /\.s?css$/,
use: [
@@ -180,6 +180,5 @@
],
};
}
export default renderer;
+705 -3548
View File
File diff suppressed because it is too large. Load diff