fix for windows path to show in project tree across platforms correctly (#11027)

* fix for windows path to show in project tree across platforms correctly

* allow retrying on project that failed to load

* test for project failed to load case

* Adding platform safe uri for database ref in tree
This commit is contained in:
Udeesha Gautam
2020-06-22 22:37:24 -07:00
committed by GitHub
parent d0b71e116b
commit cfbce96fe2
5 changed files with 60 additions and 3 deletions

View File

@@ -97,6 +97,16 @@ export function getSafeNonWindowsPath(filePath: string): string {
return '"' + filePath + '"';
}
/**
* Get safe relative path for Windows and non-Windows Platform
* This is needed to read sqlproj entried created on SSDT and opened in MAC
* '/' in tree is recognized all platforms but "\\" only by windows
*/
export function getPlatformSafeFileEntryPath(filePath: string): string {
const parts = filePath.split('\\');
return parts.join('/');
}
/**
* Read SQLCMD variables from xmlDoc and return them
* @param xmlDoc xml doc to read SQLCMD variables from. Format must be the same that sqlproj and publish profiles use

View File

@@ -85,11 +85,19 @@ export class ProjectsController {
// TODO: prompt to create new datasources.json; for now, swallow
}
else {
this.projects = this.projects.filter((e) => { return e !== newProject; });
throw err;
}
}
this.refreshProjectsTree();
try {
this.refreshProjectsTree();
}
catch (err) {
// if the project didnt load - remove it from the list of open projects
this.projects = this.projects.filter((e) => { return e !== newProject; });
throw err;
}
return newProject;
}

View File

@@ -74,7 +74,8 @@ export class Project {
throw new Error(constants.invalidDatabaseReference);
}
this.databaseReferences.push(path.parse(filepath).name);
const platformSafeFilePath = utils.getPlatformSafeFileEntryPath(filepath);
this.databaseReferences.push(path.parse(platformSafeFilePath).name);
}
}
}
@@ -250,7 +251,8 @@ export class Project {
}
public createProjectEntry(relativePath: string, entryType: EntryType): ProjectEntry {
return new ProjectEntry(Uri.file(path.join(this.projectFolderPath, relativePath)), relativePath, entryType);
let platformSafeRelativePath = utils.getPlatformSafeFileEntryPath(relativePath);
return new ProjectEntry(Uri.file(path.join(this.projectFolderPath, platformSafeRelativePath)), relativePath, entryType);
}
private findOrCreateItemGroup(containedTag?: string): any {

View File

@@ -79,6 +79,20 @@ describe.skip('ProjectsController: project controller operations', function ():
should(project.dataSources.length).equal(2); // detailed datasources tests in their own test file
});
it('Should not keep failed to load project in project list.', async function (): Promise<void> {
const folderPath = await testUtils.generateTestFolderPath();
const sqlProjPath = await testUtils.createTestSqlProjFile('empty file with no valid xml', folderPath);
const projController = new ProjectsController(testContext.apiWrapper.object, new SqlDatabaseProjectTreeViewProvider());
try {
await projController.openProject(vscode.Uri.file(sqlProjPath));
should.fail(null, null, 'The given project not expected to open');
}
catch {
should(projController.projects.length).equal(0, 'The added project should be removed');
}
});
it('Should return silently when no SQL object name provided in prompts', async function (): Promise<void> {
for (const name of ['', ' ', undefined]) {
testContext.apiWrapper.reset();

View File

@@ -93,4 +93,27 @@ describe.skip('Project Tree tests', function (): void {
DatabaseProjectItemType.file,
DatabaseProjectItemType.file]);
});
it('Should be able to parse windows relative path as platform safe path', async function (): Promise<void> {
const root = os.platform() === 'win32' ? 'Z:\\' : '/';
const proj = new Project(vscode.Uri.file(`${root}TestProj.sqlproj`).fsPath);
// nested entries before explicit top-level folder entry
// also, ordering of files/folders at all levels
proj.files.push(proj.createProjectEntry('someFolder1\\MyNestedFolder1\\MyFile1.sql', EntryType.File));
proj.files.push(proj.createProjectEntry('someFolder1\\MyNestedFolder2', EntryType.Folder));
proj.files.push(proj.createProjectEntry('someFolder1\\MyFile2.sql', EntryType.File));
const tree = new ProjectRootTreeItem(proj);
should(tree.children.map(x => x.uri.path)).deepEqual([
'/TestProj.sqlproj/Data Sources',
'/TestProj.sqlproj/Database References',
'/TestProj.sqlproj/someFolder1']);
// Why are we only matching names - https://github.com/microsoft/azuredatastudio/issues/11026
should(tree.children.find(x => x.uri.path === '/TestProj.sqlproj/someFolder1')?.children.map(y => path.basename(y.uri.path))).deepEqual([
'MyNestedFolder1',
'MyNestedFolder2',
'MyFile2.sql']);
});
});