Skip to content

Commit 33e9884

Browse files
author
safwaneettih
committed
refactor: remove legacy slug handling from repository storage and sync manager
1 parent 2203586 commit 33e9884

File tree

3 files changed

+3
-143
lines changed

3 files changed

+3
-143
lines changed

src/storage/repositoryStorage.ts

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -31,67 +31,3 @@ export function decodeRepositorySlug(slug: string): string {
3131
throw new Error(`Failed to decode repository slug: ${error}`);
3232
}
3333
}
34-
35-
/**
36-
* Check if a slug is in the legacy underscore-based format
37-
* Legacy slugs are lowercase and contain underscores but are not valid base64url
38-
* @param slug The slug to check
39-
* @returns True if the slug appears to be in legacy format
40-
*/
41-
export function isLegacySlug(slug: string): boolean {
42-
// Base64url uses alphanumeric, dash, and underscore characters
43-
// Legacy slugs are lowercase with underscores from URL character replacement
44-
45-
// If it successfully decodes as base64url and looks like a URL, it's not legacy
46-
try {
47-
const decoded = Buffer.from(slug, 'base64url').toString('utf8');
48-
// Check if decoded string looks like a URL (has protocol or domain pattern)
49-
if (decoded.includes('://') || decoded.match(/^[a-z0-9\-\.]+\.[a-z]{2,}/i)) {
50-
return false;
51-
}
52-
} catch {
53-
// If decoding fails, it might be legacy
54-
}
55-
56-
// Legacy format characteristics:
57-
// - All lowercase
58-
// - Contains underscores (from character replacement)
59-
// - May contain dots and dashes
60-
// - No uppercase letters (base64url can have uppercase)
61-
const hasUppercase = /[A-Z]/.test(slug);
62-
const hasUnderscores = slug.includes('_');
63-
const isLowercase = slug === slug.toLowerCase();
64-
65-
// Legacy: lowercase with underscores and no uppercase
66-
return isLowercase && hasUnderscores && !hasUppercase;
67-
}
68-
69-
/**
70-
* Convert a legacy underscore-based slug to the original URL
71-
* This is a best-effort conversion and may not be 100% accurate for all cases
72-
* @param legacySlug The legacy underscore-based slug
73-
* @returns The reconstructed repository URL
74-
*/
75-
export function legacySlugToUrl(legacySlug: string): string {
76-
// Reverse the legacy encoding process:
77-
// 1. Replace underscores with slashes
78-
// 2. Add https:// prefix
79-
const reconstructed = legacySlug.replace(/_/g, '/');
80-
81-
// Add protocol if not present
82-
if (!reconstructed.startsWith('http://') && !reconstructed.startsWith('https://')) {
83-
return 'https://' + reconstructed;
84-
}
85-
86-
return reconstructed;
87-
}
88-
89-
/**
90-
* Migrate a legacy slug to the new base64url format
91-
* @param legacySlug The legacy underscore-based slug
92-
* @returns The new base64url-encoded slug
93-
*/
94-
export function migrateLegacySlug(legacySlug: string): string {
95-
const url = legacySlugToUrl(legacySlug);
96-
return encodeRepositorySlug(url);
97-
}

src/syncManager.ts

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { StatusBarManager, SyncStatus } from './statusBarManager';
55
import { Logger } from './utils/logger';
66
import { NotificationManager } from './utils/notifications';
77
import { GitApiManager, GitTreeItem } from './utils/gitProvider';
8-
import { encodeRepositorySlug, isLegacySlug, migrateLegacySlug } from './storage/repositoryStorage';
8+
import { encodeRepositorySlug } from './storage/repositoryStorage';
99
import { GitProviderFactory } from './utils/gitProviderFactory';
1010
import { FileSystemManager } from './utils/fileSystem';
1111
import { AzureDevOpsApiManager } from './utils/azureDevOps';
@@ -687,74 +687,12 @@ export class SyncManager {
687687
} else {
688688
this.logger.debug('No repository storage to migrate');
689689
}
690-
691-
// Migrate legacy underscore-based slugs to base64url format
692-
await this.migrateLegacySlugs();
693690
} catch (error) {
694691
this.logger.error('Error during repository storage migration', error instanceof Error ? error : undefined);
695692
// Don't throw - allow extension to continue even if migration fails
696693
}
697694
}
698695

699-
/**
700-
* Migrate legacy underscore-based repository slugs to base64url format
701-
*/
702-
private async migrateLegacySlugs(): Promise<void> {
703-
try {
704-
if (!await this.fileSystem.directoryExists(this.repoStorageDir)) {
705-
this.logger.debug('No repository storage directory, skipping legacy slug migration');
706-
return;
707-
}
708-
709-
const fs = require('fs').promises;
710-
const entries = await fs.readdir(this.repoStorageDir, { withFileTypes: true });
711-
712-
let migratedCount = 0;
713-
714-
for (const entry of entries) {
715-
if (!entry.isDirectory()) {
716-
continue;
717-
}
718-
719-
const oldSlug = entry.name;
720-
721-
// Check if this is a legacy slug
722-
if (!isLegacySlug(oldSlug)) {
723-
continue;
724-
}
725-
726-
try {
727-
// Convert to new base64url slug
728-
const newSlug = migrateLegacySlug(oldSlug);
729-
const oldPath = path.join(this.repoStorageDir, oldSlug);
730-
const newPath = path.join(this.repoStorageDir, newSlug);
731-
732-
// Check if new path already exists (avoid overwriting)
733-
if (await this.fileSystem.directoryExists(newPath)) {
734-
this.logger.warn(`Skipping migration of ${oldSlug}: target ${newSlug} already exists`);
735-
continue;
736-
}
737-
738-
// Rename directory
739-
await fs.rename(oldPath, newPath);
740-
migratedCount++;
741-
this.logger.info(`Migrated legacy slug: ${oldSlug} -> ${newSlug}`);
742-
} catch (error) {
743-
this.logger.error(`Failed to migrate legacy slug ${oldSlug}`, error instanceof Error ? error : undefined);
744-
}
745-
}
746-
747-
if (migratedCount > 0) {
748-
this.logger.info(`Successfully migrated ${migratedCount} legacy repository slug(s) to base64url format`);
749-
} else {
750-
this.logger.debug('No legacy slugs found to migrate');
751-
}
752-
} catch (error) {
753-
this.logger.error('Error during legacy slug migration', error instanceof Error ? error : undefined);
754-
// Don't throw - allow extension to continue even if migration fails
755-
}
756-
}
757-
758696
/**
759697
* Get the storage path for a specific repository
760698
*/

src/ui/promptTreeProvider.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as fs from 'fs';
44
import { ConfigManager } from '../configManager';
55
import { FileSystemManager } from '../utils/fileSystem';
66
import { Logger } from '../utils/logger';
7-
import { decodeRepositorySlug, isLegacySlug, legacySlugToUrl } from '../storage/repositoryStorage';
7+
import { decodeRepositorySlug } from '../storage/repositoryStorage';
88

99
export interface PromptInfo {
1010
name: string;
@@ -610,22 +610,8 @@ export class PromptTreeDataProvider implements vscode.TreeDataProvider<PromptTre
610610

611611
/**
612612
* Decode a repository URL from its encoded directory name
613-
* Supports both new base64url format and legacy underscore-based format
614613
*/
615614
private decodeRepositoryUrl(encodedUrl: string): string {
616-
// Check if this is a legacy underscore-based slug
617-
if (isLegacySlug(encodedUrl)) {
618-
this.logger.debug(`Detected legacy slug format: ${encodedUrl}`);
619-
return legacySlugToUrl(encodedUrl);
620-
}
621-
622-
// Use new base64url decoding
623-
try {
624-
return decodeRepositorySlug(encodedUrl);
625-
} catch (error) {
626-
// Fallback to legacy format if base64url decoding fails
627-
this.logger.warn(`Failed to decode as base64url, falling back to legacy format: ${encodedUrl}`);
628-
return legacySlugToUrl(encodedUrl);
629-
}
615+
return decodeRepositorySlug(encodedUrl);
630616
}
631617
}

0 commit comments

Comments
 (0)