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

[.NETCore][RFC] Rewrite reading of csproj files #1029

Closed
SabotageAndi opened this issue Feb 16, 2018 · 28 comments
Closed

[.NETCore][RFC] Rewrite reading of csproj files #1029

SabotageAndi opened this issue Feb 16, 2018 · 28 comments
Labels
.NET Core Support request-for-comment SpecFlow Team Backlog this issue are in the backlog of the SpecFlow Team
Milestone

Comments

@SabotageAndi
Copy link
Contributor

With SpecFlow 2.2, we changed to reading the csproj via XML. This has limited support for the SDK project format.
To get back complete MSBuild functionality, we require a design time build of the project.

For that we could use https://github.com/daveaglick/Buildalyzer.

@gasparnagy
Copy link
Contributor

This looks good. I've run into a problem with our XML-based solution not supporting "Exclude" anyway.

@SabotageAndi SabotageAndi added the SpecFlow Team Backlog this issue are in the backlog of the SpecFlow Team label Mar 1, 2018
@kant2002
Copy link
Contributor

@SabotageAndi what are the area which should be changed for this task? it looks like relatively small and self-contained so I take a stab on it.

@SabotageAndi
Copy link
Contributor Author

@SabotageAndi
Copy link
Contributor Author

@kant2002
Copy link
Contributor

You are reading my thoughts. One last question, does tests has solutions with .NET Core, or that's up to me create such projects to test against them? There mention that Exclude is not supported in the project. Should I try to add test for that scenario as well ?

@SabotageAndi
Copy link
Contributor Author

Currently everything is still in full framework (most .NET 4.5, some higher) and it will take some time until we compile for .NET Standard/Core 2.0. Reason is that we need to upgrade our own test infrastructure first. @david1995, @nesli92 and I are working on that currently.
Project file reading is currently only done when the code-behind file is generated, so the Generator Tests project is good for it. I would suggest you create a new folder/namespace and put there the test classes. Please don't create a new test project only for this.

About Exclude: yes, please add tests for that. And also other ugly MSBuild stuff you can imagine ;-)

@kant2002
Copy link
Contributor

I try to replace the reading logic for MSBuild files, and try following approaches

  • Buildalyzer
  • Direct MSBuild API

The issue for both approaches, is that Buildalizer which dependes on the latest MSBuild API and MSBuild API v15 require at least net46 instead of net45 which is target for TechTalk.SpecFlow.Generator
So it looks like this project has to be retargeted to net46 to be able use MBuild API either directly, or indirectly via Buildalizer

/cc: @SabotageAndi

@SabotageAndi
Copy link
Contributor Author

@kant2002 I have to think about this tomorrow. I wasn't aware that MSBuild needs now net46.

kant2002 added a commit to kant2002/SpecFlow that referenced this issue Apr 22, 2018
- Control usage of new implementation via SPECFLOW_USE_MSBUILDAPI to be able test both implementations side-by-side
- Update TechTalk.SpecFlow.Generator to net46 to be able use MSBuild API, and propagate changes where required across projects which depends on the TechTalk.SpecFlow.Generator
- Update MSBuild API to 15.6. This change may be not needed, but, I strongly suspect that it will play more nicely with all version of .NET Core up to not yet released .NET Core 2.1
- Add tests on the exclude folder
- Change test a bit to take into account that paths `.\filename` and `filename` appear as two items via MSBuild API, and I dont think that duplicate items is desired behavior
- Implementation of MSBuildApiProjectReader is just old resurrected implementation using MSBuild API with small changes

See SpecFlowOSS#1029
kant2002 added a commit to kant2002/SpecFlow that referenced this issue Apr 22, 2018
- Control usage of new implementation via SPECFLOW_USE_MSBUILDAPI to be able test both implementations side-by-side
- Update TechTalk.SpecFlow.Generator to net46 to be able use MSBuild API, and propagate changes where required across projects which depends on the TechTalk.SpecFlow.Generator
- Update MSBuild API to 15.6. This change may be not needed, but, I strongly suspect that it will play more nicely with all version of .NET Core up to not yet released .NET Core 2.1
- Add tests on the exclude folder
- Change test a bit to take into account that paths `.\filename` and `filename` appear as two items via MSBuild API, and I dont think that duplicate items is desired behavior
- Implementation of MSBuildApiProjectReader is just old resurrected implementation using MSBuild API with small changes

See SpecFlowOSS#1029
@kant2002
Copy link
Contributor

I added PR to show you the what could be done in case if you decide go with net46. Also I notice that MSBuild API previously does not require net46 and was happy with net45 since you use them in the project, but right now it is a must.

@kant2002
Copy link
Contributor

@SabotageAndi Any ideas how to proceed?

@SabotageAndi
Copy link
Contributor Author

@kant2002 Yes, but didn't had yet the time to write.
.NET 4.6 shouldn't be a problem in the generator code, as this is executed at compile time at the user. So .NET 4.6 is only a requirement to run the tools. And this comes with VS2017.
The Runtime (the TechTalk.SpecFlow assembly) has to be still on .NET 4.5, so that it can be used against .NET 4.5 applications.

My idea is to add some properties for the different TFM- combinations into the Directory.builds.props.
So we have one centralized point where we can configure where we use which .NET framework.

So it is fine when you upgrade the projects to net46.

About this PR: is this the old MSBuild code? Looks familiar.

Some info about it: We switched to the XML parsing because we had caching issues with MSBuild. Sometimes it didn't get it, when you add new files. For that reason, I wanted to have a look at design time builds. After reading this blogpost (https://daveaglick.com/posts/running-a-design-time-build-with-msbuild-apis) I was sure, I don't want to call the MSBuild API direct and use Buildalyzer instead.

@kant2002
Copy link
Contributor

@SabotageAndi Buildalizer support only .NET Standard 2.0

NU1202: Package Buildalyzer 0.4.0 is not compatible with net46 (.NETFramework,Version=v4.6). Package Buildalyzer 0.4.0 supports: netstandard2.0 (.NETStandard,Version=v2.0)

So my question, should project targeting for Generator and all other projects to be bumped to .NET 4.7 which support NET Standard 2.0, or I should go to Buildalizer and made PR to support 4.6. This is depends mostly on your willingness to support VS2015, if follow same logic, then generator process would be on the machine which has VS2017, then net47 is fine, and Buildalizer could be used without modifications.

@SabotageAndi
Copy link
Contributor Author

Go for net47/netstandard 2.0 and let's see if we get feedback to support on the generator side lower frameworks.

@kant2002
Copy link
Contributor

@SabotageAndi Followup with changes which not related to major task, but I do anyway (or want to do).

  • Remove build.bat from solution (seen that you remove file from source control)
  • I see PostCompile.bat, should I remove it, or change paths inside it to correspond to the new targeting scheme
  • After that change, where I target TechTalk.SpecFlow.Generator to net461;netstandard2.0, I essentially implement [.NETCore] Compile for .NET Standard/Core 2.0 #1038 if I understand that task correctly. This changes propagate across different solution and I attempt to keep minimum version available. Projects which target net45 keep supporting it and just add target netstandard2.0.
  • Update appveyor.yml to reflect changes in output path after project retargeting.

Questions:

  • Does I allowed to keep net461;netstandard2.0 + net45;netstandard2.0, or you prefer to go with just net461. For me add support for netstandard2.0 is safe change, but it's up to you to decide should it go separately or not.
  • Does there any places like appveyor.yml or PostCompile.bat where I have to change paths, to match new project framework targeting.

@kant2002
Copy link
Contributor

See #1127 as additional motivation for me to have netstandard2.0 support sooner

@SabotageAndi
Copy link
Contributor Author

@kant2002

build.bat - stupid solution items, I forgot to delete it there.

PostCompile.bat: this is currently needed for Integration & Specs tests. We want to get rid of it. This work will happen in this PR: #1128. The tests doesn't run in the DotNetCore at the moment at all, so simple don't change it. Wenn we merge #1128 it should hopefully be gone.

I was with my comment above to vague and misunderstanding. Before we add netstandard2.0 to the TargetFrameworks I would like to clean up things at get other things to work. So at least issues #1035, #1036, #1031. If we don't do the things before, the addition of netstandard2.0 will get messy. So until that, please stay at the full framework at the moment.

AppVeyor: yes, please update the path and disable the Integration & Specs tests at the moment. They will only fail.

About additional changes because of path changes: for sure the creation of the NuGet packages. You have to adjust the props file like https://github.com/techtalk/SpecFlow/blob/master/Installer/NuGetPackages/SpecFlow/SpecFlow.nuspec.props

Everything answered?

@kant2002
Copy link
Contributor

@SabotageAndi Yes you answer all what I need. Probably I have enough input, so let me update code and I will comeback with changes.

@SabotageAndi
Copy link
Contributor Author

@kant2002 Cool! I am looking forward to the PR.

@kant2002
Copy link
Contributor

@SabotageAndi Next problem is that Buildalizer is don't strongly signed. I think that if take old MSBuild API code and don't use GlobalProjects that could be solve problems with caching of files which you do mention. I see rationale with going with Buildalyzer, just provide alternatives if strong signing will be blocker.

@SabotageAndi
Copy link
Contributor Author

@kant2002 I opened an issue at Buildalyzer about it (phmonte/Buildalyzer#51).
Does it hold you back if it is currently not strong name signed?

@kant2002
Copy link
Contributor

@SabotageAndi I implement change, that's actually straightforward, but not able to run tests, since Buildalyzer assembly could not be loaded.

@kant2002
Copy link
Contributor

I would propose stick with MSBuild API, accept PR, create another issue mentioning Buildalizer, Create PR for that small change and wait until Buildalyzer respond

@SabotageAndi
Copy link
Contributor Author

@kant2002 I extracted the TFMs into the Directory.build.props and also added a central location to enable/disable strong name signing (PR #1133)

It's now a simple MSBuild property (https://github.com/techtalk/SpecFlow/blob/DotNetCore/Directory.Build.props#L12) which is currently false.
So all strong name signing is disabled for now.

@kant2002
Copy link
Contributor

@SabotageAndi Cool, let me rebase and add Buldalyzer

kant2002 added a commit to kant2002/SpecFlow that referenced this issue Apr 24, 2018
- Control usage of new implementation via SPECFLOW_USE_MSBUILDAPI to be able test both implementations side-by-side
- Update TechTalk.SpecFlow.Generator to net46 to be able use MSBuild API, and propagate changes where required across projects which depends on the TechTalk.SpecFlow.Generator
- Update MSBuild API to 15.6. This change may be not needed, but, I strongly suspect that it will play more nicely with all version of .NET Core up to not yet released .NET Core 2.1
- Add tests on the exclude folder
- Change test a bit to take into account that paths `.\filename` and `filename` appear as two items via MSBuild API, and I dont think that duplicate items is desired behavior
- Implementation of MSBuildApiProjectReader is just old resurrected implementation using MSBuild API with small changes

See SpecFlowOSS#1029
@kant2002
Copy link
Contributor

@SabotageAndi I'm ready. Please take a look at PR

SabotageAndi pushed a commit that referenced this issue Apr 25, 2018
* Rewrite MSBuild reader to use MSBuild API
- Control usage of new implementation via SPECFLOW_USE_MSBUILDAPI to be able test both implementations side-by-side
- Update TechTalk.SpecFlow.Generator to net46 to be able use MSBuild API, and propagate changes where required across projects which depends on the TechTalk.SpecFlow.Generator
- Update MSBuild API to 15.6. This change may be not needed, but, I strongly suspect that it will play more nicely with all version of .NET Core up to not yet released .NET Core 2.1
- Add tests on the exclude folder
- Change test a bit to take into account that paths `.\filename` and `filename` appear as two items via MSBuild API, and I dont think that duplicate items is desired behavior
- Implementation of MSBuildApiProjectReader is just old resurrected implementation using MSBuild API with small changes

See #1029

* Update Generator project to use net461 target framework

* Comment out not working test projects

* Use Buildalizer for loading projects

* Remove XML project reader completely
This is justified by fact that supporting it, means reimplementing whole MSBuild logic, which is not reasonable. Also for loading plugins would be needed read PackageReferences from the projects, and this would be problematic implement correctly. Current implementation is also flawled. See #1102, and wellknown fact that Exclude property on the MSBuild items is not supported
@SabotageAndi SabotageAndi moved this from Todo to In Progess in .NET Core Support May 14, 2018
@kant2002
Copy link
Contributor

Does something else should be done on this issue ?

@SabotageAndi
Copy link
Contributor Author

For now, yes. I forgot to close the issue after merging the PR.

.NET Core Support automation moved this from In Progess to Done May 22, 2018
@lock
Copy link

lock bot commented Jul 9, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jul 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
.NET Core Support request-for-comment SpecFlow Team Backlog this issue are in the backlog of the SpecFlow Team
Projects
No open projects
Development

No branches or pull requests

3 participants