1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

respond to review comments

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-04-14 08:38:22 -04:00
parent a384dd06f7
commit 9550f0754c
4 changed files with 44 additions and 39 deletions

View File

@ -144,9 +144,9 @@ export class ExtensionDiscovery {
// Extension add is detected by watching "<extensionDir>/package.json" add // Extension add is detected by watching "<extensionDir>/package.json" add
.on("add", this.handleWatchFileAdd) .on("add", this.handleWatchFileAdd)
// Extension remove is detected by watching "<extensionDir>" unlink // Extension remove is detected by watching "<extensionDir>" unlink
.on("unlinkDir", this.handleWatchUnlinkDir) .on("unlinkDir", this.handleWatchUnlinkEvent)
// Extension remove is detected by watching "<extensionSymLink>" unlink // Extension remove is detected by watching "<extensionSymLink>" unlink
.on("unlink", this.handleWatchUnlinkDir); .on("unlink", this.handleWatchUnlinkEvent);
} }
handleWatchFileAdd = async (manifestPath: string) => { handleWatchFileAdd = async (manifestPath: string) => {
@ -185,36 +185,39 @@ export class ExtensionDiscovery {
} }
}; };
handleWatchUnlinkDir = async (filePath: string) => { /**
// filePath is the non-symlinked path to the extension folder * Handle any unlink event, filtering out non-package.json links so the delete code
// this.packagesJson.dependencies value is the non-symlinked path to the extension folder * only happens once per extension.
// LensExtensionId in extension-loader is the symlinked path to the extension folder manifest file * @param filePath The absolute path to either a folder or file in the extensions folder
*/
handleWatchUnlinkEvent = async (filePath: string): Promise<void> => {
// Check that the removed path is directly under this.localFolderPath // Check that the removed path is directly under this.localFolderPath
// Note that the watcher can create unlink events for subdirectories of the extension // Note that the watcher can create unlink events for subdirectories of the extension
const extensionFolderName = path.basename(filePath); const extensionFolderName = path.basename(filePath);
const expectedPath = path.relative(this.localFolderPath, filePath); const expectedPath = path.relative(this.localFolderPath, filePath);
if (expectedPath === extensionFolderName) { if (expectedPath !== extensionFolderName) {
const extension = Array.from(this.extensions.values()).find((extension) => extension.absolutePath === filePath); return;
if (extension) {
const extensionName = extension.manifest.name;
// If the extension is deleted manually while the application is running, also remove the symlink
await this.removeSymlinkByPackageName(extensionName);
// The path to the manifest file is the lens extension id
// Note that we need to use the symlinked path
const lensExtensionId = extension.manifestPath;
this.extensions.delete(extension.id);
logger.info(`${logModule} removed extension ${extensionName}`);
this.events.emit("remove", lensExtensionId as LensExtensionId);
} else {
logger.warn(`${logModule} extension ${extensionFolderName} not found, can't remove`);
}
} }
const extension = Array.from(this.extensions.values()).find((extension) => extension.absolutePath === filePath);
if (!extension) {
return void logger.warn(`${logModule} extension ${extensionFolderName} not found, can't remove`);
}
const extensionName = extension.manifest.name;
// If the extension is deleted manually while the application is running, also remove the symlink
await this.removeSymlinkByPackageName(extensionName);
// The path to the manifest file is the lens extension id
// Note: that we need to use the symlinked path
const lensExtensionId = extension.manifestPath;
this.extensions.delete(extension.id);
logger.info(`${logModule} removed extension ${extensionName}`);
this.events.emit("remove", lensExtensionId);
}; };
/** /**
@ -282,11 +285,11 @@ export class ExtensionDiscovery {
await fse.ensureDir(this.nodeModulesPath); await fse.ensureDir(this.nodeModulesPath);
await fse.ensureDir(this.localFolderPath); await fse.ensureDir(this.localFolderPath);
try { const extensions = await this.ensureExtensions();
return await this.ensureExtensions();
} finally { this.isLoaded = true;
this.isLoaded = true;
} return extensions;
} }
/** /**

View File

@ -290,18 +290,18 @@ export class ExtensionLoader {
protected requireExtension(extension: InstalledExtension): LensExtensionConstructor | null { protected requireExtension(extension: InstalledExtension): LensExtensionConstructor | null {
const entryPointName = ipcRenderer ? "renderer" : "main"; const entryPointName = ipcRenderer ? "renderer" : "main";
const extensionEntryPointRelativePath = extension.manifest[entryPointName]; const extRelativePath = extension.manifest[entryPointName];
if (!extensionEntryPointRelativePath) { if (!extRelativePath) {
return null; return null;
} }
const extensionEntryPointAbsolutePath = path.resolve(path.join(path.dirname(extension.manifestPath), extensionEntryPointRelativePath)); const extAbsolutePath = path.resolve(path.join(path.dirname(extension.manifestPath), extRelativePath));
try { try {
return __non_webpack_require__(extensionEntryPointAbsolutePath).default; return __non_webpack_require__(extAbsolutePath).default;
} catch (error) { } catch (error) {
logger.error(`${logModule}: can't load extension main at ${extensionEntryPointAbsolutePath}: ${error}`, { extension, error }); logger.error(`${logModule}: can't load extension main at ${extAbsolutePath}: ${error}`, { extension, error });
} }
} }

View File

@ -8,7 +8,7 @@ import { ipcRenderer } from "electron";
export enum ExtensionInstallationState { export enum ExtensionInstallationState {
INSTALLING = "installing", INSTALLING = "installing",
UNINSTALLING = "uninstalling", UNINSTALLING = "uninstalling",
IDLE = "IDLE", IDLE = "idle",
} }
const Prefix = "[ExtensionInstallationStore]"; const Prefix = "[ExtensionInstallationStore]";

View File

@ -159,7 +159,7 @@ async function validatePackage(filePath: string): Promise<LensExtensionManifest>
parseJson: true, parseJson: true,
}); });
if (!manifest.lens && !manifest.renderer) { if (!manifest.main && !manifest.renderer) {
throw new Error(`${manifestFilename} must specify "main" and/or "renderer" fields`); throw new Error(`${manifestFilename} must specify "main" and/or "renderer" fields`);
} }
@ -335,7 +335,7 @@ async function attemptInstall(request: InstallRequest, d?: Disposer): Promise<vo
<div className="flex column gaps"> <div className="flex column gaps">
<b>Extension Install Collision:</b> <b>Extension Install Collision:</b>
<p>The <em>{name}</em> extension is currently {curState.toLowerCase()}.</p> <p>The <em>{name}</em> extension is currently {curState.toLowerCase()}.</p>
<p>Will not procede with this current install request.</p> <p>Will not proceed with this current install request.</p>
</div> </div>
); );
} }
@ -366,12 +366,14 @@ async function attemptInstall(request: InstallRequest, d?: Disposer): Promise<vo
await unpackExtension(validatedRequest, dispose); await unpackExtension(validatedRequest, dispose);
} else { } else {
dispose(); dispose();
await fse.unlink(validatedRequest.tempFile).catch(noop);
} }
}} /> }} />
</div>, </div>,
{ {
onClose() { onClose() {
dispose(); dispose();
fse.unlink(validatedRequest.tempFile).catch(noop);
} }
} }
); );