diff --git a/apps/vs-code-designer/src/app/projectConsistency/__test__/projectFilesConsistency.test.ts b/apps/vs-code-designer/src/app/projectConsistency/__test__/projectFilesConsistency.test.ts index 2078492a4f0..db92c03a5ed 100644 --- a/apps/vs-code-designer/src/app/projectConsistency/__test__/projectFilesConsistency.test.ts +++ b/apps/vs-code-designer/src/app/projectConsistency/__test__/projectFilesConsistency.test.ts @@ -46,10 +46,6 @@ vi.mock('fs-extra', () => ({ pathExists: vi.fn(), readFile: vi.fn(), readdir: vi.fn(), - lstat: vi.fn(), - readlink: vi.fn(), - symlink: vi.fn(), - remove: vi.fn(), })); vi.mock('../../utils/appSettings/localSettings', async (importActual) => { @@ -93,10 +89,6 @@ const mockedFse = fse as unknown as { pathExists: ReturnType; readFile: ReturnType; readdir: ReturnType; - lstat: ReturnType; - readlink: ReturnType; - symlink: ReturnType; - remove: ReturnType; }; const mockedAddOrUpdate = localSettings.addOrUpdateLocalAppSettings as unknown as ReturnType; const mockedGetLocalSettingsJson = localSettings.getLocalSettingsJson as unknown as ReturnType; @@ -898,115 +890,6 @@ describe('projectFilesConsistency', () => { }); }); }); - - describe('artifacts junction', () => { - const designTimeDir = `${projectPath}/workflow-designtime`; - const artifactsTarget = `${projectPath}/Artifacts`; - const artifactsLink = `${designTimeDir}/Artifacts`; - - beforeEach(() => { - // Default: valid design-time directory so host/settings are not rewritten - const hostPath = `${designTimeDir}/host.json`; - const settingsPath = `${designTimeDir}/local.settings.json`; - const validHost = JSON.stringify({ - version: '2.0', - extensionBundle: { id: 'Microsoft.Azure.Functions.ExtensionBundle.Workflows', version: '[1.*, 2.0.0)' }, - extensions: { workflow: { settings: { [workflowOperationDiscoveryHostModeKey]: 'true' } } }, - }); - const validSettings = JSON.stringify({ - Values: { - APP_KIND: 'workflowapp', - FUNCTIONS_WORKER_RUNTIME: 'dotnet', - FUNCTIONS_INPROC_NET8_ENABLED: '1', - ProjectDirectoryPath: projectPath, - }, - }); - mockFiles({ [designTimeDir]: '', [hostPath]: validHost, [settingsPath]: validSettings, [artifactsTarget]: '' }); - mockedFse.lstat.mockRejectedValue(new Error('ENOENT')); - mockedFse.symlink.mockResolvedValue(undefined); - mockedFse.readlink.mockResolvedValue(artifactsTarget); - mockedFse.remove.mockResolvedValue(undefined); - }); - - it('creates a junction when Artifacts exists and no link is present', async () => { - mockedFse.lstat.mockRejectedValue(new Error('ENOENT')); - - await ensureDesignTimeFiles(context, projectPath); - - expect(mockedFse.symlink).toHaveBeenCalledWith( - expect.stringContaining('Artifacts'), - expect.stringContaining('workflow-designtime'), - 'junction' - ); - }); - - it('does not create a junction when Artifacts folder does not exist', async () => { - // Remove Artifacts from the mock file system - mockFiles({ - [designTimeDir]: '', - [`${designTimeDir}/host.json`]: JSON.stringify({ - version: '2.0', - extensionBundle: { id: 'Microsoft.Azure.Functions.ExtensionBundle.Workflows', version: '[1.*, 2.0.0)' }, - extensions: { workflow: { settings: { [workflowOperationDiscoveryHostModeKey]: 'true' } } }, - }), - [`${designTimeDir}/local.settings.json`]: JSON.stringify({ - Values: { - APP_KIND: 'workflowapp', - FUNCTIONS_WORKER_RUNTIME: 'dotnet', - FUNCTIONS_INPROC_NET8_ENABLED: '1', - ProjectDirectoryPath: projectPath, - }, - }), - }); - - await ensureDesignTimeFiles(context, projectPath); - - expect(mockedFse.symlink).not.toHaveBeenCalled(); - }); - - it('does not recreate junction when it already points to correct target', async () => { - mockedFse.lstat.mockResolvedValue({ isSymbolicLink: () => true }); - mockedFse.readlink.mockResolvedValue(artifactsTarget); - - await ensureDesignTimeFiles(context, projectPath); - - expect(mockedFse.symlink).not.toHaveBeenCalled(); - expect(mockedFse.remove).not.toHaveBeenCalled(); - }); - - it('recreates junction when it points to wrong target', async () => { - mockedFse.lstat.mockResolvedValue({ isSymbolicLink: () => true }); - mockedFse.readlink.mockResolvedValue('/some/other/path'); - - await ensureDesignTimeFiles(context, projectPath); - - expect(mockedFse.remove).toHaveBeenCalled(); - expect(mockedFse.symlink).toHaveBeenCalledWith( - expect.stringContaining('Artifacts'), - expect.stringContaining('workflow-designtime'), - 'junction' - ); - }); - - it('does not overwrite a real directory at the link path', async () => { - mockedFse.lstat.mockResolvedValue({ isSymbolicLink: () => false }); - - await ensureDesignTimeFiles(context, projectPath); - - expect(mockedFse.symlink).not.toHaveBeenCalled(); - expect(mockedFse.remove).not.toHaveBeenCalled(); - }); - - it('logs a warning when symlink creation fails', async () => { - mockedFse.lstat.mockRejectedValue(new Error('ENOENT')); - mockedFse.symlink.mockRejectedValue(new Error('EPERM')); - - await ensureDesignTimeFiles(context, projectPath); - - const lines = loggedLines(); - expect(lines.some((l) => l.includes('junction'))).toBe(true); - }); - }); }); describe('ensureHostFile', () => { diff --git a/apps/vs-code-designer/src/app/projectConsistency/projectFilesConsistency.ts b/apps/vs-code-designer/src/app/projectConsistency/projectFilesConsistency.ts index fc7c2cd7a08..2f8e857aeb0 100644 --- a/apps/vs-code-designer/src/app/projectConsistency/projectFilesConsistency.ts +++ b/apps/vs-code-designer/src/app/projectConsistency/projectFilesConsistency.ts @@ -5,7 +5,6 @@ import { ProjectDirectoryPathKey, appKindSetting, - artifactsDirectory, connectionsFileName, designTimeDirectoryName, extensionBundleId, @@ -270,10 +269,6 @@ export async function ensureDesignTimeFiles( changedArtifacts.push(`${designTimeArtifactPrefix}${localSettingsFileName}`); } - const artifactsTarget = path.join(projectPath, artifactsDirectory); - const artifactsLink = path.join(designTimeDirectory.fsPath, artifactsDirectory); - await ensureArtifactsSymlink(artifactsLink, artifactsTarget); - return { changedArtifacts }; } @@ -427,25 +422,6 @@ async function readFileTextSafe(filePath: string): Promise { return ''; } -async function ensureArtifactsSymlink(artifactsLink: string, artifactsTarget: string): Promise { - if (await fse.pathExists(artifactsTarget)) { - try { - const linkStat = await fse.lstat(artifactsLink).catch(() => null); - if (linkStat && linkStat.isSymbolicLink()) { - const currentTarget = await fse.readlink(artifactsLink); - if (!arePathsEqual(currentTarget, artifactsTarget)) { - await fse.remove(artifactsLink); - await fse.symlink(artifactsTarget, artifactsLink, 'junction'); - } - } else if (!linkStat) { - await fse.symlink(artifactsTarget, artifactsLink, 'junction'); - } - } catch { - ext.outputChannel.appendLog(localize('artifactsJunctionFailed', 'Failed to create Artifacts junction in design-time directory.')); - } - } -} - function arePathsEqual(path1?: string, path2?: string): boolean { if (typeof path1 !== 'string' || typeof path2 !== 'string' || !path1 || !path2) { return false;