MCPcopy Index your code
hub / github.com/codeaashu/claude-code / cacheMarketplaceFromGit

Function cacheMarketplaceFromGit

src/utils/plugins/marketplaceManager.ts:1084–1178  ·  view source on GitHub ↗

* Cache a marketplace from a git repository * * Clones or updates a git repository containing marketplace data. * If the repository already exists at cachePath, pulls the latest changes. * If pulling fails, removes the directory and re-clones. * * Example repository structure: * ``` * my-mar

(
  gitUrl: string,
  cachePath: string,
  ref?: string,
  sparsePaths?: string[],
  onProgress?: MarketplaceProgressCallback,
  options?: { disableCredentialHelper?: boolean },
)

Source from the content-addressed store, hash-verified

1082 * @param onProgress - Optional callback to report progress
1083 */
1084async function cacheMarketplaceFromGit(
1085 gitUrl: string,
1086 cachePath: string,
1087 ref?: string,
1088 sparsePaths?: string[],
1089 onProgress?: MarketplaceProgressCallback,
1090 options?: { disableCredentialHelper?: boolean },
1091): Promise<void> {
1092 const fs = getFsImplementation()
1093
1094 // Attempt incremental update; fall back to re-clone if the repo is absent,
1095 // stale, or otherwise not updatable. Using pull-first avoids a stat-before-operate
1096 // TOCTOU check: gitPull returns non-zero when cachePath is missing or has no .git.
1097 const timeoutSec = Math.round(getPluginGitTimeoutMs() / 1000)
1098 safeCallProgress(
1099 onProgress,
1100 `Refreshing marketplace cache (timeout: ${timeoutSec}s)…`,
1101 )
1102
1103 // Reconcile sparse-checkout config before pulling. If this requires a re-clone
1104 // (Sparse→Full transition) or fails (missing dir, not a repo), skip straight
1105 // to the rm+clone fallback.
1106 const reconcileResult = await reconcileSparseCheckout(cachePath, sparsePaths)
1107 if (reconcileResult.code === 0) {
1108 const pullStarted = performance.now()
1109 const pullResult = await gitPull(cachePath, ref, {
1110 disableCredentialHelper: options?.disableCredentialHelper,
1111 sparsePaths,
1112 })
1113 logPluginFetch(
1114 'marketplace_pull',
1115 gitUrl,
1116 pullResult.code === 0 ? 'success' : 'failure',
1117 performance.now() - pullStarted,
1118 pullResult.code === 0 ? undefined : classifyFetchError(pullResult.stderr),
1119 )
1120 if (pullResult.code === 0) return
1121 logForDebugging(`git pull failed, will re-clone: ${pullResult.stderr}`, {
1122 level: 'warn',
1123 })
1124 } else {
1125 logForDebugging(
1126 `sparse-checkout reconcile requires re-clone: ${reconcileResult.stderr}`,
1127 )
1128 }
1129
1130 try {
1131 await fs.rm(cachePath, { recursive: true })
1132 // rm succeeded — a stale or partially-cloned directory existed; log for diagnostics
1133 logForDebugging(
1134 `Found stale marketplace directory at ${cachePath}, cleaning up to allow re-clone`,
1135 { level: 'warn' },
1136 )
1137 safeCallProgress(
1138 onProgress,
1139 'Found stale directory, cleaning up and re-cloning…',
1140 )
1141 } catch (rmError) {

Callers 2

loadAndCacheMarketplaceFunction · 0.85
refreshMarketplaceFunction · 0.85

Calls 12

getFsImplementationFunction · 0.85
getPluginGitTimeoutMsFunction · 0.85
safeCallProgressFunction · 0.85
reconcileSparseCheckoutFunction · 0.85
gitPullFunction · 0.85
logPluginFetchFunction · 0.85
classifyFetchErrorFunction · 0.85
logForDebuggingFunction · 0.85
isENOENTFunction · 0.85
redactUrlCredentialsFunction · 0.85
gitCloneFunction · 0.70
errorMessageFunction · 0.50

Tested by

no test coverage detected