Skip to content

Commit 0fa5751

Browse files
committed
Allow WorkspacePaths to be empty if we're not in a workspace
We were previously adding the initial working directory as a fallback if there was no workspace. However, this led to new VS Code windows (not in a workspace) enumerating all files in the home directory (if that's what the client had to default to, without a workspace folder). And this could even spam permission requests on more secure systems such as macOS. So we just need to let be an empty enumerable.
1 parent a691981 commit 0fa5751

File tree

3 files changed

+24
-17
lines changed

3 files changed

+24
-17
lines changed

src/PowerShellEditorServices/Services/Extension/EditorOperationsService.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ public async Task SaveFileAsync(string currentPath, string newSavePath)
192192
}
193193

194194
// NOTE: This name is now outdated since we don't have a way to distinguish one workspace
195-
// from another for the extension API.
195+
// from another for the extension API. TODO: Should this be an empty string if we have no
196+
// workspaces?
196197
public string GetWorkspacePath() => _workspaceService.InitialWorkingDirectory;
197198

198199
public string[] GetWorkspacePaths() => _workspaceService.WorkspacePaths.ToArray();

src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ public WorkspaceService(ILoggerFactory factory)
104104

105105
#region Public Methods
106106

107-
public IEnumerable<string> WorkspacePaths => WorkspaceFolders.Count == 0
108-
? new List<string> { InitialWorkingDirectory }
109-
: WorkspaceFolders.Select(i => i.Uri.GetFileSystemPath());
107+
public IEnumerable<string> WorkspacePaths => WorkspaceFolders.Select(i => i.Uri.GetFileSystemPath());
110108

111109
/// <summary>
112110
/// Gets an open file in the workspace. If the file isn't open but exists on the filesystem, load and return it.

test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs

+21-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Runtime.InteropServices;
88
using Microsoft.Extensions.Logging.Abstractions;
99
using Microsoft.PowerShell.EditorServices.Services;
10-
using Microsoft.PowerShell.EditorServices.Test.Shared;
1110
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
1211
using Xunit;
1312
using Microsoft.PowerShell.EditorServices.Utility;
@@ -27,6 +26,10 @@ public class WorkspaceTests
2726

2827
internal static ScriptFile CreateScriptFile(string path) => new(path, "", VersionUtils.PSVersion);
2928

29+
// Remember that LSP does weird stuff to the drive letter, so we have to convert it to a URI
30+
// and back to ensure that drive letter gets lower cased and everything matches up.
31+
private static string s_workspacePath =>
32+
DocumentUri.FromFileSystemPath(Path.GetFullPath("Fixtures/Workspace")).GetFileSystemPath();
3033

3134
[Fact]
3235
public void CanResolveWorkspaceRelativePath()
@@ -76,16 +79,21 @@ internal static WorkspaceService FixturesWorkspace()
7679
{
7780
return new WorkspaceService(NullLoggerFactory.Instance)
7881
{
79-
InitialWorkingDirectory = TestUtilities.NormalizePath("Fixtures/Workspace")
82+
WorkspaceFolders =
83+
{
84+
new WorkspaceFolder { Uri = DocumentUri.FromFileSystemPath(s_workspacePath) }
85+
}
8086
};
8187
}
8288

8389
[Fact]
8490
public void HasDefaultForWorkspacePaths()
8591
{
8692
WorkspaceService workspace = FixturesWorkspace();
87-
string actual = Assert.Single(workspace.WorkspacePaths);
88-
Assert.Equal(workspace.InitialWorkingDirectory, actual);
93+
string workspacePath = Assert.Single(workspace.WorkspacePaths);
94+
Assert.Equal(s_workspacePath, workspacePath);
95+
// We shouldn't assume an initial working directory since none was given.
96+
Assert.Null(workspace.InitialWorkingDirectory);
8997
}
9098

9199
// These are the default values for the EnumeratePSFiles() method
@@ -129,18 +137,18 @@ public void CanRecurseDirectoryTree()
129137

130138
List<string> expected = new()
131139
{
132-
Path.Combine(workspace.InitialWorkingDirectory, "nested", "donotfind.ps1"),
133-
Path.Combine(workspace.InitialWorkingDirectory, "nested", "nestedmodule.psd1"),
134-
Path.Combine(workspace.InitialWorkingDirectory, "nested", "nestedmodule.psm1"),
135-
Path.Combine(workspace.InitialWorkingDirectory, "rootfile.ps1")
140+
Path.Combine(s_workspacePath, "nested", "donotfind.ps1"),
141+
Path.Combine(s_workspacePath, "nested", "nestedmodule.psd1"),
142+
Path.Combine(s_workspacePath, "nested", "nestedmodule.psm1"),
143+
Path.Combine(s_workspacePath, "rootfile.ps1")
136144
};
137145

138146
// .NET Core doesn't appear to use the same three letter pattern matching rule although the docs
139147
// suggest it should be find the '.ps1xml' files because we search for the pattern '*.ps1'
140148
// ref https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles?view=netcore-2.1#System_IO_Directory_GetFiles_System_String_System_String_System_IO_EnumerationOptions_
141149
if (RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework"))
142150
{
143-
expected.Insert(3, Path.Combine(workspace.InitialWorkingDirectory, "other", "other.ps1xml"));
151+
expected.Insert(3, Path.Combine(s_workspacePath, "other", "other.ps1xml"));
144152
}
145153

146154
Assert.Equal(expected, actual);
@@ -157,7 +165,7 @@ public void CanRecurseDirectoryTreeWithLimit()
157165
maxDepth: 1,
158166
ignoreReparsePoints: s_defaultIgnoreReparsePoints
159167
);
160-
Assert.Equal(new[] { Path.Combine(workspace.InitialWorkingDirectory, "rootfile.ps1") }, actual);
168+
Assert.Equal(new[] { Path.Combine(s_workspacePath, "rootfile.ps1") }, actual);
161169
}
162170

163171
[Fact]
@@ -173,16 +181,16 @@ public void CanRecurseDirectoryTreeWithGlobs()
173181
);
174182

175183
Assert.Equal(new[] {
176-
Path.Combine(workspace.InitialWorkingDirectory, "nested", "nestedmodule.psd1"),
177-
Path.Combine(workspace.InitialWorkingDirectory, "rootfile.ps1")
184+
Path.Combine(s_workspacePath, "nested", "nestedmodule.psd1"),
185+
Path.Combine(s_workspacePath, "rootfile.ps1")
178186
}, actual);
179187
}
180188

181189
[Fact]
182190
public void CanOpenAndCloseFile()
183191
{
184192
WorkspaceService workspace = FixturesWorkspace();
185-
string filePath = Path.GetFullPath(Path.Combine(workspace.InitialWorkingDirectory, "rootfile.ps1"));
193+
string filePath = Path.GetFullPath(Path.Combine(s_workspacePath, "rootfile.ps1"));
186194

187195
ScriptFile file = workspace.GetFile(filePath);
188196
Assert.Equal(workspace.GetOpenedFiles(), new[] { file });

0 commit comments

Comments
 (0)