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