Skip to content

Commit 7fbf0f7

Browse files
authored
fix: uninstall at repository level was deleting files in github folder unrelated (#127)
1 parent dfc91d4 commit 7fbf0f7

File tree

5 files changed

+779
-122
lines changed

5 files changed

+779
-122
lines changed

src/services/BundleInstaller.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,26 @@ export class BundleInstaller {
351351
await this.updateLockfileOnUninstall(installed.bundleId);
352352
}
353353

354-
// Remove installation directory
354+
// Remove installation directory (bundle cache)
355+
// For repository scope, the installPath may point to .github which is NOT the bundle cache.
356+
// The actual bundle cache is in extension global storage under bundles/{bundleId}.
357+
// We should only remove the bundle cache directory, not the .github directory.
355358
if (installed.installPath && fs.existsSync(installed.installPath)) {
356-
await this.removeDirectory(installed.installPath);
357-
this.logger.debug(`Removed directory: ${installed.installPath}`);
359+
if (installed.scope === 'repository' && this.isGitHubDirectory(installed.installPath)) {
360+
// Skip removal of .github directory - unsyncBundle already handled removing synced files
361+
// and we don't want to remove unrelated files (workflows, CODEOWNERS, etc.)
362+
this.logger.debug(`Skipping removal of .github directory: ${installed.installPath}`);
363+
364+
// Remove the actual bundle cache from global storage instead
365+
const bundleCachePath = this.getInstallDirectory(installed.bundleId, 'repository');
366+
if (bundleCachePath && fs.existsSync(bundleCachePath) && bundleCachePath !== installed.installPath) {
367+
await this.removeDirectory(bundleCachePath);
368+
this.logger.debug(`Removed bundle cache directory: ${bundleCachePath}`);
369+
}
370+
} else {
371+
await this.removeDirectory(installed.installPath);
372+
this.logger.debug(`Removed directory: ${installed.installPath}`);
373+
}
358374
}
359375

360376
this.logger.info('Bundle uninstalled successfully');
@@ -753,6 +769,23 @@ export class BundleInstaller {
753769
}
754770
}
755771

772+
/**
773+
* Check if a path is the .github directory or a subdirectory of it.
774+
* Used to prevent accidental removal of the .github folder which may contain
775+
* unrelated files like workflows, CODEOWNERS, etc.
776+
*
777+
* @param dirPath - The directory path to check
778+
* @returns true if the path is .github or ends with /.github
779+
*/
780+
private isGitHubDirectory(dirPath: string): boolean {
781+
const normalizedPath = path.normalize(dirPath);
782+
const baseName = path.basename(normalizedPath);
783+
784+
// Check if the directory itself is named .github
785+
// This handles both "/path/to/.github" and ".github"
786+
return baseName === '.github';
787+
}
788+
756789
/**
757790
* Remove directory recursively
758791
* Handles symbolic links safely by removing only the link, not the target

src/services/LockfileManager.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,9 @@ export class LockfileManager {
933933
seenIds.add(bundleId);
934934
const filesMissing = await this.checkFilesMissing(entry);
935935
// Create bundle with commitMode: 'commit' (from main lockfile)
936+
// TODO: installPath should point to the bundle cache in global storage, not .github
937+
// The .github directory is where files are synced, not where the bundle is installed.
938+
// This is a workaround - BundleInstaller.uninstall() handles this case specially.
936939
const installedBundle = createInstalledBundleFromLockfile(bundleId, entry, {
937940
installPath: path.join(this.repositoryPath, '.github'),
938941
filesMissing,

0 commit comments

Comments
 (0)