Skip to content
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

Refactor dotnet code gen #233

Merged
merged 24 commits into from
Jul 12, 2024
Merged

Conversation

clrudolphi
Copy link
Contributor

@clrudolphi clrudolphi commented Jun 28, 2024

🤔 What's changed?

Rewrote the Dotnet code generation script to adopt the ruby erb gem approach used for other languages.
Modified the target .NET Framework settings by eliminating the use of .NET45 - targeting .NETStandard2.0 only.

Used a DevContainer so you'll see a devcontainer.json in the file set.

⚡️ What's your motivation?

To bring the .NET implementation to parity with the java version.

🏷️ What kind of change is this?

  • 🏦 Refactoring/debt/DX (improvement to code design, tooling, etc. without changing behaviour)

♻️ Anything particular you want feedback on?

Per the question I posted on issue #230, does the ordering of properties of a entity matter when serialized? The serialization I have does not match the sequence of properties shown in the CCK examples.

I've used a Microsoft provided devcontainer image. Do you mind? Or should that be changed to the github image?

📋 Checklist:

  • I agree to respect and uphold the Cucumber Community Code of Conduct
  • I've changed the behaviour of the code
    • [X ] I have added/updated tests to cover my changes.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.
  • [X ] Users should know about my change
    • [X ] I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.

This text was originally generated from a template, then edited by hand. You can modify the template here.

Sorry, something went wrong.

@clrudolphi clrudolphi marked this pull request as draft June 28, 2024 18:03
@mpkorstanje mpkorstanje marked this pull request as ready for review June 28, 2024 18:49
@mpkorstanje mpkorstanje marked this pull request as draft June 28, 2024 18:49
Copy link
Contributor

@mpkorstanje mpkorstanje left a comment

Choose a reason for hiding this comment

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

Looks good over all.

But I'm a bit puzzled as to why the CI hasn't been activated. I would have expected some build failures. I'll look into that.

For the mean time, I left a few comments. The first two are for myself. The others you may want to address.

var jsonOptions = new JsonSerializerOptions();
jsonOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
jsonOptions.Converters.Add(new CustomEnumConverter<StepDefinitionPatternType>());
jsonOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
Copy link
Contributor

Choose a reason for hiding this comment

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

These json options are non trivial and will have to be replicated by anyone who wants to serialize messages. So I think it would be prudent to provide a serializer and deserializer class as part of the messages library. This should hopefully prevent any mistakes from taking hold.

You may also want to look at some of the other utility classes that come with messages.

https://github.com/cucumber/messages/tree/main/java/src/main/java/io/cucumber/messages

When comparing do note that unlike many other languages, Java does not have an out of the box json serializer On the other hand, the libraries Java does have update quite frequently. To avoid this cascading down from messages, the MessageToNdjsonWriter is constructed with a Serializer interface instead. This allows us to keep the serializer library at the edge of the dependency tree.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the quick feedback. I'll take a look at whether the utility classes make sense in the dotnet ecosystem.
I'll double check with Gaspar about the .net version (5 v 8).
And I'll port over the Java test suite (or something similar).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Completed. Please take a look at what was added to the support classes to make serialization easier. It aligns with how the Java implementation works.

@mpkorstanje
Copy link
Contributor

Per the question I posted on issue #230, does the ordering of properties of a entity matter when serialized? The serialization I have does not match the sequence of properties shown in the CCK examples.

Answered: #230 (comment). The order does not matter.

I've used a Microsoft provided devcontainer image. Do you mind? Or should that be changed to the github image?

As long as that choice falls within the common practices in the .Net ecosystem that is okay. The goal is to make sure the next contributor familiar with .Net understands what is going on.

I also don't think the Github provided containers are available on Dockerhub.

@clrudolphi
Copy link
Contributor Author

Updated the PR to include a ChangeLog entry.
Revised the code gen script to house all the generated C# classes in a /generated folder.
Added support classes in alignment with what the Java implementation has (for serialization support and TimeStamp conversions).
Added tests for the support classes (again, similar in nature to what the Java implementation does)
Dropped target framework support for .NET Framework 4.x (leaving .NET Standard 2.0 as the target).

@clrudolphi clrudolphi marked this pull request as ready for review June 30, 2024 01:20
@clrudolphi
Copy link
Contributor Author

@mpkorstanje please add @gasparnagy as a reviewer of this PR. Thanks

@mpkorstanje mpkorstanje requested a review from gasparnagy June 30, 2024 07:54
@@ -22,5 +22,6 @@ jobs:

- name: run tests
run: |
make
echo "No tests yet"
exit 1
Copy link
Contributor

@mpkorstanje mpkorstanje Jun 30, 2024

Choose a reason for hiding this comment

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

Got CI to trigger properly. Please add something sensible here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i've modified that to invoke dotnet test

… testing step. (Updated minimum dotnet version from 5.x to 8.x)

Restored default.mk in the dotnet folder (was mistakenly deleted in an earlier commit)
Copy link
Member

@gasparnagy gasparnagy left a comment

Choose a reason for hiding this comment

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

Thx for the code, it looks good.

I added my notes. Most of them minor, there are only a few tricky questions.

…n: a) whether to use long or int, b) whether to take a dependency on System.Text.Json package or find another option.
@luke-hill
Copy link
Contributor

Dependent on the timeframes involved this will maybe require a large conflict resolution as I'm in the process of refactoring the codegen (Only a small refactor, but lots of moving of files around), here: #228

I'm currently at a bit of an impasse in terms of contributing for the coming weeks, so if this is merged in in the next 1-2 weeks you'll have no issues and I'll fix up conflicts my end. But just letting you know 👍

…he PR.

Put a lock around the creation of the json serialization options singleton to address what appear to be threading issues while running tests during github CI.
@mpkorstanje
Copy link
Contributor

@luke-hill cheers.

@clrudolphi @gasparnagy take your time, I won't be looking at opensource this week until the end of the weekend.

return NdjsonSerializer.Deserialize<Envelope>(json);
}

public static T Deserialize<T>(string json)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would only ever expect users of this API to read and write envelopes. So Serialize<T> and Deserialize<T> can probably be package private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had left it public in order to test it (via elements more granular than Envelopes). Now that we're over that hurdle, I'll remove the single such test and make these private.

@clrudolphi
Copy link
Contributor Author

I've also added a line to MessagetoNdjsonReader and Writer classes to Close their internally held streamwriter upon Dispose().

Copy link
Contributor

@luke-hill luke-hill left a comment

Choose a reason for hiding this comment

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

Popped some linting suggestions. I've tried to keep them brief / relevant.

I think it's probably best we get this merged in first and then merge my codegen stuff in after as there's still a lot of stuff to tidy up but probably best I tackle it.

@clrudolphi
Copy link
Contributor Author

Thanks for your review comments so far.
I think the only outstanding item is the comment from @luke-hill about the dotnet generation script and the complexity required when declaring Nullable properties/fields.

@clrudolphi
Copy link
Contributor Author

@mpkorstanje @luke-hill Any chance to close this out today or tomorrow? I'm going on holiday until the 1st of August and would be good to finish this so that @luke-hill can proceed with his other refactoring.

@luke-hill
Copy link
Contributor

@clrudolphi consider all my comments that have not been addressed to be "deferable" I don't want to hold anything up.

Just consider the actual dotnet stuff from Gaspar / Rien now. I can do some more fine tuning after your stuff is merged in a separate PR entirely to both this one and my companion one. Which would probably make things easier for you to review also.

Copy link
Contributor

@mpkorstanje mpkorstanje left a comment

Choose a reason for hiding this comment

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

Looks good!

@gasparnagy any remarks? If not, feel free to merge.

Copy link
Member

@gasparnagy gasparnagy left a comment

Choose a reason for hiding this comment

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

Shit it 😀!

@gasparnagy gasparnagy merged commit 3f63d3b into cucumber:main Jul 12, 2024
26 checks passed
@clrudolphi
Copy link
Contributor Author

Shit it 😀!

Funniest merge approval comment ever!

@gasparnagy
Copy link
Member

😀 Autocorrect... But you know what I meant.

@mpkorstanje
Copy link
Contributor

@gasparnagy have you made a release before?

@gasparnagy
Copy link
Member

No, I don't think so.

@luke-hill
Copy link
Contributor

Just posting here. Let's hold off releasing until I get my codegen stuff in also. As then it's a chunky enough release for a major.

@mpkorstanje
Copy link
Contributor

No problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants