Refactor the module path construction code to make it more robust and easier to maintain#26565
Refactor the module path construction code to make it more robust and easier to maintain#26565daxian-dbw merged 9 commits intoPowerShell:masterfrom
Conversation
… easier to maintain
ShellCannotBeStarted errorThere was a problem hiding this comment.
Pull request overview
This PR refactors the module path construction code in PowerShell to fix issue #26536, which involves two main problems: insufficient error diagnostics in exception fallback handling and incorrect handling of multi-path PSModulePath values from configuration files. The refactoring moves module path initialization to a static constructor, consolidates path manipulation methods, and improves error reporting by including stack traces.
Key Changes
- Moved module path initialization from instance constructor to static constructor for earlier, one-time initialization
- Refactored
UpdatePathmethod (previously split betweenAddToPathand a wrapperUpdatePath) to handle multiple semicolon/colon-separated paths in a single call - Enhanced
ReportExceptionFallbackto output complete stack traces including inner exceptions - Added test coverage for
PSModulePathconfiguration with multiple paths
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| test/powershell/Host/ConsoleHost.Tests.ps1 | Added test for PSModulePath with multiple paths from config file; contains platform-specific path separator issues |
| src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs | Refactored module path construction: moved initialization to static constructor, consolidated UpdatePath logic, improved PathContainsSubstring with better return semantics |
| src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs | Enhanced exception reporting to include stack traces for debugging ShellCannotBeStarted errors; contains potential null reference issues |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
iSazonov
left a comment
There was a problem hiding this comment.
On top of ModuleIntrinsics.cs I see we define Tracer. It would be nice to add to the trace source and result path strings for more easy diagnostics.
| // Local function to normalize a path by removing trailing directory separators. | ||
| static string NormalizePath(string path) | ||
| { | ||
| string normalizedPath = path.TrimEnd(Path.DirectorySeparatorChar); |
There was a problem hiding this comment.
Why not use NormalizePath method from FileSystemProvider? Then we will follow the basic PowerShell behavior regarding directory separators.
Otherwise, we could use Path.TrimEndingDirectorySeparator()
There was a problem hiding this comment.
Path.TrimEndingDirectorySeparator doesn't remove duplicate trailing directory separators. It only removes the ending one. But I think it should be practically fine, and also, I favor over simplicity. We can get back to it if it turns out to be an issue.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Ready to merge. |
|
@iSazonov Thanks for the review! |
… easier to maintain (PowerShell#26565)
PR Summary
Fix #26536
There are 2 issues surfaced from #26536 that we need to address:
ReportExceptionFallback(Exception e, string header)does not write out stack trace of the exception, which makes it hard to diagnose failures likeShellCannotBeStarted.UpdatePathmethod used in module path construction doesn't handle the case wherepersonalModulePathToUsemay contain multiple paths separated by thePathSperator(user can definePSModulePathinpowershell.config.jsonwith such a value).The fixes are:
ReportExceptionFallback(Exception e, string header), at the end.UpdatePathmethod.PathContainsSubstringmethod. Change to a difference approach that is much more efficient.AddPathmethod and rename it to beUpdatePathSetModulePath()to not blindly add a path separator when the environment variablePSModulePathis initially not set in all scopes.SetModulePath()in the static constructor ofModuleIntrinsicsinstead of the instance constructor. So, we only need to construct the module path once per process (instead of once per a new Runspace).With the changes, PowerShell won't crash even if the personal module path is like
C:\Users\marcv\OneDrive - company & name namepart2\Dokumente\PowerShell\Modulesas reported in the issue.PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header