mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Include bundled extensions in package.json (#6715)
* bundle extensions to asar Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * make build fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
146cae0b1c
commit
012944d562
12 files changed
+55
-108
No files matched your search
@@ -18,6 +18,7 @@ export default getGlobalOverride(applicationInformationInjectable, () => ({
|
||||
sentryDsn: "",
|
||||
contentSecurityPolicy: "script-src 'unsafe-eval' 'self'; frame-src http://*.localhost:*/; img-src * data:",
|
||||
welcomeRoute: "/welcome",
|
||||
extensions: [],
|
||||
},
|
||||
copyright: "some-copyright-information",
|
||||
description: "some-descriptive-text",
|
||||
|
||||
@@ -10,7 +10,6 @@ import extensionsStoreInjectable from "../extensions-store/extensions-store.inje
|
||||
import extensionInstallationStateStoreInjectable from "../extension-installation-state-store/extension-installation-state-store.injectable";
|
||||
import installExtensionInjectable from "../extension-installer/install-extension/install-extension.injectable";
|
||||
import extensionPackageRootDirectoryInjectable from "../extension-installer/extension-package-root-directory/extension-package-root-directory.injectable";
|
||||
import installExtensionsInjectable from "../extension-installer/install-extensions/install-extensions.injectable";
|
||||
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import pathExistsInjectable from "../../common/fs/path-exists.injectable";
|
||||
@@ -28,6 +27,7 @@ import getRelativePathInjectable from "../../common/path/get-relative-path.injec
|
||||
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
||||
import removePathInjectable from "../../common/fs/remove-path.injectable";
|
||||
import homeDirectoryPathInjectable from "../../common/os/home-directory-path.injectable";
|
||||
import applicationInformationInjectable from "../../common/vars/application-information.injectable";
|
||||
import lensResourcesDirInjectable from "../../common/vars/lens-resources-dir.injectable";
|
||||
|
||||
const extensionDiscoveryInjectable = getInjectable({
|
||||
@@ -39,7 +39,6 @@ const extensionDiscoveryInjectable = getInjectable({
|
||||
extensionInstallationStateStore: di.inject(extensionInstallationStateStoreInjectable),
|
||||
isCompatibleExtension: di.inject(isCompatibleExtensionInjectable),
|
||||
installExtension: di.inject(installExtensionInjectable),
|
||||
installExtensions: di.inject(installExtensionsInjectable),
|
||||
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
|
||||
resourcesDirectory: di.inject(lensResourcesDirInjectable),
|
||||
readJsonFile: di.inject(readJsonFileInjectable),
|
||||
@@ -59,6 +58,7 @@ const extensionDiscoveryInjectable = getInjectable({
|
||||
getRelativePath: di.inject(getRelativePathInjectable),
|
||||
joinPaths: di.inject(joinPathsInjectable),
|
||||
homeDirectoryPath: di.inject(homeDirectoryPathInjectable),
|
||||
applicationInformation: di.inject(applicationInformationInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import type { ExtensionsStore } from "../extensions-store/extensions-store";
|
||||
import type { ExtensionLoader } from "../extension-loader";
|
||||
import type { LensExtensionId, LensExtensionManifest } from "../lens-extension";
|
||||
import type { ExtensionInstallationStateStore } from "../extension-installation-state-store/extension-installation-state-store";
|
||||
import type { PackageJson } from "type-fest";
|
||||
import { extensionDiscoveryStateChannel } from "../../common/ipc/extension-handling";
|
||||
import { requestInitialExtensionDiscovery } from "../../renderer/ipc";
|
||||
import type { ReadJson } from "../../common/fs/read-json-file.injectable";
|
||||
@@ -20,7 +19,6 @@ import type { Logger } from "../../common/logger";
|
||||
import type { PathExists } from "../../common/fs/path-exists.injectable";
|
||||
import type { Watch } from "../../common/fs/watch/watch.injectable";
|
||||
import type { Stats } from "fs";
|
||||
import { constants } from "fs";
|
||||
import type { LStat } from "../../common/fs/lstat.injectable";
|
||||
import type { ReadDirectory } from "../../common/fs/read-directory.injectable";
|
||||
import type { EnsureDirectory } from "../../common/fs/ensure-dir.injectable";
|
||||
@@ -32,6 +30,7 @@ import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable"
|
||||
import type { GetRelativePath } from "../../common/path/get-relative-path.injectable";
|
||||
import type { RemovePath } from "../../common/fs/remove-path.injectable";
|
||||
import type TypedEventEmitter from "typed-emitter";
|
||||
import type { ApplicationInformation } from "../../common/vars/application-information.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
readonly extensionLoader: ExtensionLoader;
|
||||
@@ -43,9 +42,9 @@ interface Dependencies {
|
||||
readonly isProduction: boolean;
|
||||
readonly fileSystemSeparator: string;
|
||||
readonly homeDirectoryPath: string;
|
||||
readonly applicationInformation: ApplicationInformation;
|
||||
isCompatibleExtension: (manifest: LensExtensionManifest) => boolean;
|
||||
installExtension: (name: string) => Promise<void>;
|
||||
installExtensions: (packageJsonPath: string, packagesJson: PackageJson) => Promise<void>;
|
||||
readJsonFile: ReadJson;
|
||||
pathExists: PathExists;
|
||||
removePath: RemovePath;
|
||||
@@ -137,14 +136,6 @@ export class ExtensionDiscovery {
|
||||
return this.dependencies.joinPaths(this.dependencies.extensionPackageRootDirectory, manifestFilename);
|
||||
}
|
||||
|
||||
get inTreeTargetPath(): string {
|
||||
return this.dependencies.joinPaths(this.dependencies.extensionPackageRootDirectory, "extensions");
|
||||
}
|
||||
|
||||
get inTreeFolderPath(): string {
|
||||
return this.dependencies.joinPaths(this.dependencies.resourcesDirectory, "extensions");
|
||||
}
|
||||
|
||||
get nodeModulesPath(): string {
|
||||
return this.dependencies.joinPaths(this.dependencies.extensionPackageRootDirectory, "node_modules");
|
||||
}
|
||||
@@ -329,26 +320,6 @@ export class ExtensionDiscovery {
|
||||
);
|
||||
|
||||
await this.dependencies.removePath(this.dependencies.joinPaths(this.dependencies.extensionPackageRootDirectory, "package-lock.json"));
|
||||
|
||||
const canWriteToInTreeFolder = await this.dependencies.accessPath(this.inTreeFolderPath, constants.W_OK);
|
||||
|
||||
if (canWriteToInTreeFolder) {
|
||||
// Set bundled folder path to static/extensions
|
||||
this.bundledFolderPath = this.inTreeFolderPath;
|
||||
} else {
|
||||
// Remove e.g. /Users/<username>/Library/Application Support/LensDev/extensions
|
||||
await this.dependencies.removePath(this.inTreeTargetPath);
|
||||
|
||||
// Create folder e.g. /Users/<username>/Library/Application Support/LensDev/extensions
|
||||
await this.dependencies.ensureDirectory(this.inTreeTargetPath);
|
||||
|
||||
// Copy static/extensions to e.g. /Users/<username>/Library/Application Support/LensDev/extensions
|
||||
await this.dependencies.copy(this.inTreeFolderPath, this.inTreeTargetPath);
|
||||
|
||||
// Set bundled folder path to e.g. /Users/<username>/Library/Application Support/LensDev/extensions
|
||||
this.bundledFolderPath = this.inTreeTargetPath;
|
||||
}
|
||||
|
||||
await this.dependencies.ensureDirectory(this.nodeModulesPath);
|
||||
await this.dependencies.ensureDirectory(this.localFolderPath);
|
||||
|
||||
@@ -382,7 +353,7 @@ export class ExtensionDiscovery {
|
||||
protected async getByManifest(manifestPath: string, { isBundled = false } = {}): Promise<InstalledExtension | null> {
|
||||
try {
|
||||
const manifest = await this.dependencies.readJsonFile(manifestPath) as unknown as LensExtensionManifest;
|
||||
const id = this.getInstalledManifestPath(manifest.name);
|
||||
const id = isBundled ? manifestPath : this.getInstalledManifestPath(manifest.name);
|
||||
const isEnabled = this.dependencies.extensionsStore.isEnabled({ id, isBundled });
|
||||
const extensionDir = this.dependencies.getDirnameOfPath(manifestPath);
|
||||
const npmPackage = this.dependencies.joinPaths(extensionDir, `${manifest.name}-${manifest.version}.tgz`);
|
||||
@@ -417,39 +388,24 @@ export class ExtensionDiscovery {
|
||||
const userExtensions = await this.loadFromFolder(this.localFolderPath, bundledExtensions.map((extension) => extension.manifest.name));
|
||||
const extensions = bundledExtensions.concat(userExtensions);
|
||||
|
||||
await this.installBundledPackages(this.packageJsonPath, extensions);
|
||||
|
||||
return this.extensions = new Map(extensions.map(extension => [extension.id, extension]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write package.json to file system and install dependencies.
|
||||
*/
|
||||
installBundledPackages(packageJsonPath: string, extensions: InstalledExtension[]): Promise<void> {
|
||||
const dependencies = Object.fromEntries(
|
||||
extensions.filter(extension => extension.isBundled).map(extension => [extension.manifest.name, extension.absolutePath]),
|
||||
);
|
||||
const optionalDependencies = Object.fromEntries(
|
||||
extensions.filter(extension => !extension.isBundled).map(extension => [extension.manifest.name, extension.absolutePath]),
|
||||
);
|
||||
|
||||
return this.dependencies.installExtensions(packageJsonPath, { dependencies, optionalDependencies });
|
||||
}
|
||||
|
||||
async loadBundledExtensions(): Promise<InstalledExtension[]> {
|
||||
const extensions: InstalledExtension[] = [];
|
||||
const folderPath = this.bundledFolderPath;
|
||||
const paths = await this.dependencies.readDirectory(folderPath);
|
||||
const extensionNames = this.dependencies.applicationInformation.config.extensions || [];
|
||||
|
||||
for (const fileName of paths) {
|
||||
const absPath = this.dependencies.joinPaths(folderPath, fileName);
|
||||
for (const dirName of extensionNames) {
|
||||
const absPath = this.dependencies.joinPaths(__dirname, "..", "..", "node_modules", dirName);
|
||||
const extension = await this.loadExtensionFromFolder(absPath, { isBundled: true });
|
||||
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
if (!extension) {
|
||||
throw new Error(`Couldn't load bundled extension: ${dirName}`);
|
||||
}
|
||||
|
||||
extensions.push(extension);
|
||||
}
|
||||
this.dependencies.logger.debug(`${logModule}: ${extensions.length} extensions loaded`, { folderPath, extensions });
|
||||
this.dependencies.logger.debug(`${logModule}: ${extensions.length} extensions loaded`, { extensions });
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
|
||||
import AwaitLock from "await-lock";
|
||||
import child_process from "child_process";
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
import logger from "../../main/logger";
|
||||
import type { PackageJson } from "type-fest";
|
||||
|
||||
const logModule = "[EXTENSION-INSTALLER]";
|
||||
|
||||
@@ -38,27 +35,6 @@ export class ExtensionInstaller {
|
||||
return __non_webpack_require__.resolve("npm");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write package.json to the file system and execute npm install for it.
|
||||
*/
|
||||
installPackages = async (packageJsonPath: string, packagesJson: PackageJson): Promise<void> => {
|
||||
// Mutual exclusion to install packages in sequence
|
||||
await this.installLock.acquireAsync();
|
||||
|
||||
try {
|
||||
// Write the package.json which will be installed in .installDependencies()
|
||||
await fs.writeFile(path.join(packageJsonPath), JSON.stringify(packagesJson, null, 2), {
|
||||
mode: 0o600,
|
||||
});
|
||||
|
||||
logger.info(`${logModule} installing dependencies at ${this.dependencies.extensionPackageRootDirectory}`);
|
||||
await this.npm(...baseNpmInstallArgs);
|
||||
logger.info(`${logModule} dependencies installed at ${this.dependencies.extensionPackageRootDirectory}`);
|
||||
} finally {
|
||||
this.installLock.release();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Install single package using npm
|
||||
*/
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import extensionInstallerInjectable from "../extension-installer.injectable";
|
||||
|
||||
const installExtensionsInjectable = getInjectable({
|
||||
id: "install-extensions",
|
||||
instantiate: (di) => di.inject(extensionInstallerInjectable).installPackages,
|
||||
});
|
||||
|
||||
export default installExtensionsInjectable;
|
||||
Reference in new issue
Block a user