* Perform the actual plugin update: fetch source, calculate version, copy to cache, update disk. * This is the core update execution extracted from updatePluginOp.
({
pluginId,
pluginName,
entry,
marketplaceInstallLocation,
installation,
scope,
projectPath,
}: {
pluginId: string
pluginName: string
entry: PluginMarketplaceEntry
marketplaceInstallLocation: string
installation: { version?: string; installPath: string }
scope: PluginScope
projectPath: string | undefined
})
| 894 | * This is the core update execution extracted from updatePluginOp. |
| 895 | */ |
| 896 | async function performPluginUpdate({ |
| 897 | pluginId, |
| 898 | pluginName, |
| 899 | entry, |
| 900 | marketplaceInstallLocation, |
| 901 | installation, |
| 902 | scope, |
| 903 | projectPath, |
| 904 | }: { |
| 905 | pluginId: string |
| 906 | pluginName: string |
| 907 | entry: PluginMarketplaceEntry |
| 908 | marketplaceInstallLocation: string |
| 909 | installation: { version?: string; installPath: string } |
| 910 | scope: PluginScope |
| 911 | projectPath: string | undefined |
| 912 | }): Promise<PluginUpdateResult> { |
| 913 | const fs = getFsImplementation() |
| 914 | const oldVersion = installation.version |
| 915 | |
| 916 | let sourcePath: string |
| 917 | let newVersion: string |
| 918 | let shouldCleanupSource = false |
| 919 | let gitCommitSha: string | undefined |
| 920 | |
| 921 | // Handle remote vs local plugins |
| 922 | if (typeof entry.source !== 'string') { |
| 923 | // Remote plugin: download to temp directory first |
| 924 | const cacheResult = await cachePlugin(entry.source, { |
| 925 | manifest: { name: entry.name }, |
| 926 | }) |
| 927 | sourcePath = cacheResult.path |
| 928 | shouldCleanupSource = true |
| 929 | gitCommitSha = cacheResult.gitCommitSha |
| 930 | |
| 931 | // Calculate version from downloaded plugin. For git-subdir sources, |
| 932 | // cachePlugin captured the commit SHA before discarding the ephemeral |
| 933 | // clone (the extracted subdir has no .git, so the installPath-based |
| 934 | // fallback in calculatePluginVersion can't recover it). |
| 935 | newVersion = await calculatePluginVersion( |
| 936 | pluginId, |
| 937 | entry.source, |
| 938 | cacheResult.manifest, |
| 939 | cacheResult.path, |
| 940 | entry.version, |
| 941 | cacheResult.gitCommitSha, |
| 942 | ) |
| 943 | } else { |
| 944 | // Local plugin: use path from marketplace |
| 945 | // Stat directly — handle ENOENT inline rather than pre-checking existence |
| 946 | let marketplaceStats |
| 947 | try { |
| 948 | marketplaceStats = await fs.stat(marketplaceInstallLocation) |
| 949 | } catch (e: unknown) { |
| 950 | if (isENOENT(e)) { |
| 951 | return { |
| 952 | success: false, |
| 953 | message: `Marketplace directory not found at ${marketplaceInstallLocation}`, |
no test coverage detected