Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

[WIP] Update core-setup local tools to use S.T.Json for netstandard2.0 instead#5010

Closed
ahsonkhan wants to merge 3 commits intodotnet:masterfrom
ahsonkhan:UseInboxJsonForTask
Closed

[WIP] Update core-setup local tools to use S.T.Json for netstandard2.0 instead#5010
ahsonkhan wants to merge 3 commits intodotnet:masterfrom
ahsonkhan:UseInboxJsonForTask

Conversation

@ahsonkhan
Copy link

@ahsonkhan ahsonkhan commented Jan 19, 2019

Initial attempt to port tools-local to use the System.Text.Json source package for TFM netstandard2.0. Note: There are some API changes going through so this is still WIP. We have the JsonReader and JsonWriter available atm so only using the components that are ready.

The System.Text.Json binary is in-box on .NET Core 3.0.

I added TODOs to use the JsonDocument and Deserializer once they are available. Using the Utf8Reader in these scenarios is less than ideal and requires a lot of code change.

This PR is mainly to experiment to gather feedback and showcase the capabilities. Hence, marked as no merge.

We can't remove the reference to Newtonsoft since the tools are targeting net46 on Unix.

Is it possible to drop support for all but netstandard2.0? Otherwise, we have to conditionally include the source package.

See https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/source_package/README.md

Related PR: #5009

cc @joshfree, @bartonjs, @steveharter, @eerhardt, @KrzysztofCwalina, @JamesNK, @glennc, @ericstj

@ahsonkhan ahsonkhan added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Jan 19, 2019
string jsonFileText = projectFileReader.ReadToEnd();

// TODO: Replace the use of the Utf8JsonReader with the Deserializer once it is available.
ConfigJson configJson = GetConfigJson(jsonFileText);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a great way to deserialize a POCO object. I used the JsonReader just as an experiment.


private void ReadWritePropertyName(string propertyName, ref Utf8JsonReader reader, ref Utf8JsonWriter writer)
{
if (propertyName == "targets")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use the JsonDocument here. The order in which the "targets" property and the "libraries" property show up could affect the end results here if we use the Reader and Writer. This relies on "targets" coming up before "libraries".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!File.Exists(ConfigJsonFile))
{
throw new FileNotFoundException($"Expected file {ConfigJsonFile} was not found.");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't File.OpenText throw the same exception, and without the inherent race condition? You're just trying to provide a better exception message in some cases?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// Open the Config Json and read the values into the model
TextReader projectFileReader = File.OpenText(ConfigJsonFile);
if (projectFileReader != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't ever be null.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy/pasted from the origin impl. Will fix there.

}

// Open the Config Json and read the values into the model
TextReader projectFileReader = File.OpenText(ConfigJsonFile);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be disposed of when you're done with it; otherwise you're leaving the file open until it's eventually closed by a finalizer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these exist in the current implementation and I didn't modify most of it. I am going to remove BuildFPMToolPreReqs.Netstandard2_0.cs since we should wait for the Deserializer anyway, but will fix the issues you mentioned here.

string jsonFileText = projectFileReader.ReadToEnd();

// TODO: Replace the use of the Utf8JsonReader with the Deserializer once it is available.
ConfigJson configJson = GetConfigJson(jsonFileText);
Copy link
Member

@stephentoub stephentoub Jan 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we're opening the file, reading all of its contents into a string (which will involve converting from UTF8 to UTF16 if it's saved as UTF8), and then turning around and encoding that string into a UTF8 byte[]? Isn't the point of having a UTF8-based JSON reader to avoid that? Or it simply doesn't matter perf-wise here and this is what's cleanest?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to ask the same question, but then I realized that the reader does encoding-sniffing. So if someone saves the file as UTF-16 this would still successfully read it.

If we're willing to say "the file is UTF-8" (or, more likely, "the file is 7-bit ASCII") then this can be simplified a lot.

while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName)
{
string propertyName = reader.GetStringValue().ToLower();
if (propertyName == Maintainer_Name_String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does perf not matter here? Or could we instead compare span to span rather than materializing the string? And if we stick with strings, could the comparison be done as ordinal ignore case rather than lower casing the property name?

/// <summary>
/// Model classes for reading and storing the JSON.
/// </summary>
public class ConfigJson
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the other PR; there's a lot of duplication between this file and the alternate for this file.

@eerhardt
Copy link
Member

This PR is mainly to experiment to gather feedback and showcase the capabilities. Hence, marked as no merge.

Is the intention to ever put this code in? I don't see a valid reason for complicating this code.

@dleeapho
Copy link

dleeapho commented Aug 7, 2019

Closing as stale.

@dleeapho dleeapho closed this Aug 7, 2019
@ahsonkhan
Copy link
Author

ahsonkhan commented Aug 8, 2019

Sounds good. Will re-visit post 3.0.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

* NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants