-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Refactor ConvertTo-Json to expose JsonObject.ConvertToJson as a public API
#8682
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
|
@daxian-dbw I see most of code is simply copy-pasted. It seems old code is not ideal - should we review line by line in depth or only new API? |
|
@iSazonov This PR is purely a change on how code is organized, in order to expose the When reviewing the changes, I suggest to focus on the new APIs, how |
src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs
Outdated
Show resolved
Hide resolved
| targetCmdlet: this); | ||
|
|
||
| string output = JsonObject.ConvertToJson(objectToProcess, in context); | ||
| if (output != null) |
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.
Do we still need to check this?
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.
I believe so. In case ctrl+c is signaled, JsonObject.ConvertToJson would return null, and I think we don't want to write that null to pipeline.
I know that when the pipeline is stopping, WriteObject will throw from MshCommandRuntime._WriteObjectSkipAllowCheck, so technically it might be OK to remove this check.
But I want to play safe here. What do you think?
For comparison, please take a look at the use of Stopping in the original code path where a StopException is thrown which results in return from EndProcessing.
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.
I see that new code keep previous behavior and my thoughts was "is it useful to return null?" like $null | ConvertTo-Json | Should -Be $null
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.
Well, if we want to change that behavior, we should change the code here. JsonObject.ConvertToJson returns null only if StopException is thrown, and it has nothing to do with enabling $null | ConvertTo-Json.
Yeah, $null | ConvertTo-Json seems like a reasonable scenario, but the test should be $null | ConvertTo-Json | Should -Be "null". It's better to discuss this in a separate issue. Can you open an issue?
PS:30> [Newtonsoft.Json.JsonConvert]::SerializeObject($null) -eq "null"
True
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.
Can you open an issue?
I think @markekraus could comment. If he will confirm that the scenario is useful we'll open new issue.
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.
You never want ConvertTo-Json write $null to the pipeline. But looking at this, the only scenario that would do that is a stopping exception. I'm not sure if there is any edge case where JsonConvert.SerializeObejct() would return a null string object, nothing I have tried to create such a scenario works anyway. It may be safe to remove it, but, I think it's safer to leave it.
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.
@markekraus Thanks!
@daxian-dbw I think we need a test for $null | ConvertTo-Json.
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.
$null | ConvertTo-Json is not supported today -- the passed-in $null is ignored. Whether or not we should change the current behavior to support it should be a separate issue.
| return obj; | ||
|
|
||
| return dict; | ||
| cancellationSource.Cancel(); |
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.
Should we add tests for this?
(I'd not want.)
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 would be difficult to mimic 'ctrl+c' in the test. I have manually tested it though :)
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.
@SteveL-MSFT added such tests previously and they looks tricky. I don't like this but should ask :-)
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.
There is already a test for StopProcessing in test\powershell\Modules\Microsoft.PowerShell.Utility\ConvertTo-Json.Tests.ps1. It is not currently working perfectly, see #8645.
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.
See also: #8593
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.
Thanks @xtqqczze , I will take a look at those two PRs.
Fixes #8123
PR Summary
We have the public API
JsonObject.ConvertFromJsonto convert from JSON string in the PowerShell context. It would be good to have a public API for conversion to JSON. This PR refactors theConvertTo-Jsoncmdlet to move the core implementation toJsonObject.ConvertToJson, and makeConvertTo-Jsoncall that public method.This would help the Azure Function PowerShell worker. Currently, we depends on calling the cmdlet to convert object to JSON which is expensive. Once we have the public method
JsonObject.ConvertToJsonexposed, we can call the API directly to avoid a command invocation.PR Context
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.[feature]to your commit messages if the change is significant or affects feature tests