-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Replace Newtonsoft.Json with System.Text.Json in PSConfiguration #14411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
|
Does Team want this in 7.2? |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
7722939 to
accb74a
Compare
62944a8 to
ff0e610
Compare
test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1
Outdated
Show resolved
Hide resolved
cce9e62 to
7bb07da
Compare
|
Rebased to move to .Net 7 RC1. |
This reverts commit 7bb07da.
|
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
SteveL-MSFT
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
daxian-dbw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not finished reviewing but want to share my comments so far.
| #endif | ||
|
|
||
| if (s_cpp.SettingsFile is not null) | ||
| if (!string.IsNullOrEmpty(s_cpp.SettingsFile)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change this. Based on how it's set in TryParseSettingFileHelper, s_cpp.SettingsFile is guaranteed to not be an empty string.
| internal void SetSystemConfigFilePath(string value) | ||
| { | ||
| if (!string.IsNullOrEmpty(value) && !File.Exists(value)) | ||
| FileInfo info = new FileInfo(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why changing the original code? You didn't guard against null value.
I know you tried to check null and empty in ConsoleHost.cs, but this is an internal method, and you cannot assume it will be invoked only from that callsite.
| private readonly JObject[] configRoots; | ||
| private readonly JObject emptyConfig; | ||
| private readonly JsonSerializer serializer; | ||
| private readonly JsonObject[] _configScopeRoots; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems there is no particular gains over changing the name from configRoots to _configScopeRoots. It would make reading the changes easier if you can keep the original names.
Also, regarding using the prefix _ for class members, I understand it's preferred naming pattern, but given the rest member names don't have the prefix, it would be better to not use it for this PR too to keep consistency. If wanted, a separate PR should be used to fix the code styles.
| /// <param name="key">The string key of the value.</param> | ||
| /// <param name="defaultValue">The default value to return if the key is not present.</param> | ||
| private T ReadValueFromFile<T>(ConfigScope scope, string key, T defaultValue = default) | ||
| [return: NotNullIfNotNull("defaultValue")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| [return: NotNullIfNotNull("defaultValue")] | |
| [return: NotNullIfNotNull(nameof(defaultValue))] |
| { | ||
| string fileName = GetConfigFilePath(scope); | ||
| JObject configData = configRoots[(int)scope]; | ||
| var configScopeData = _configScopeRoots[(int)scope]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, keep the name configData would be helpful to review.
| using var stream = OpenFileStreamWithRetry(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); | ||
| using var jsonReader = new JsonTextReader(new StreamReader(stream)); | ||
| using var reader = new StreamReader(stream); | ||
| string jsonString = reader.ReadToEnd(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could potentially create LOH allocation.
|
I don't fully understand the gains of this work, especially given that it's a breaking change.
|
Intention is to remove dependency on Newtonsoft.Json at all. It is impossible to do this in one PR, only step by step. Before I continue with the PR. I'd want to get a conclusion from MSFT team - do we want to rid of Newtonsoft.Json in the milestone? |
I think this largely depends on whether we can retain the same behavior as of today. If breaking changes are inevitable, then I personally tend to not making the change, but of course, it would be helpful to understand the scale and risky level of those breaking changes. Besides, I have 2 more concerns:
|
.Net implementation fully follows JSON standard. So users cannot say that PowerShell cmdlets do not work correctly. Current JSON cmdlets could be published on PowerShellGet site in a compatibility module.
It seems .Net continue distribute Newtonsoft.Json. |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
|
@daxian-dbw can you mark this issue for Committee Review to get a conclusion and move this forward? |
|
@PowerShell/powershell-committee Please review to decide whether this PR is desired. Please see the comments starting from #14411 (comment) for reference and context. |
|
@PowerShell/powershell-committee reviewed this. We agree that this is the right change towards removing dependency on NewtonSoft the for the engine to read |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
|
After merging SG for PSVersionTable the config reading takes 20% in startup scenario. |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
PR Summary
Use System.Text.Json instead of Newtonsoft.Json in PSConfiguration.
Perf win is ~11% in startup scenario (pwsh -c exit) with two config files (user and system). It is ~60 ms on my system.
Breaking change because System.Text.Json have many minor (by design) breaking changes compared with Netonsoft.Json.
So I had to change
"true"ontruein powershell.config.json file in tests.Before the PR:

After the PR:

PR Context
Related #14268
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.