Docfx: Migrating our projects from net46 to netstandard 2.0

Created on 16 Aug 2017  ยท  69Comments  ยท  Source: dotnet/docfx

https://github.com/dotnet/standard/blob/master/docs/versions/netstandard2.0.md
https://gist.github.com/davidfowl/8939f305567e1755412d6dc0b8baf1b7
Steps:

  • [ ] 1. Upgrade projects to net461
  • [ ] 2. Update documentation that VS 2017 Preview Update 3 is required
  • [ ] 3. Upgrade base projects to netstardard2.0 one by one

Blockers:

Most helpful comment

@tintoy I've worked out what the change was that caused the test failures. One is that the changing to use Json.Net returns the object in a different format to the JavascriptSerializer and the other is that originally it was pulling the data from the submodule specs. After refactoring the folder structure the pathing was off so you added the specs to the repo which are now different to the submodule which is where the "new" failure come from as the submodule hasn't been updated in awhile.

I'm pretty sure i've got a fix for the object format and i'm just working on regenerating the strongly typed objects from the spec, Would you like me to open a pull request to your repo when i'm done?

All 69 comments

v3.0?

Hi @vicancy, do you have any particular place you'd prefer that I start? Otherwise, I'm happy to just dive in at the deep end and see where I get up to :)

Work starting here.

@tintoy Looks cool!

A couple of tests are failing, but I'm just checking to see if they actually succeed without these changes :)

@tintoy If you are using VS 15.3 and the tests are Metadata related, it is possibly an env issue with MSBuild, opening All.sln from VS2017 Developer Command can fix it.

Ah yes, thanks - those are the ones that are failing :)
I can probably fix that in another PR, I think (ran into a similar problem on another project).

All good, with your suggested workaround, all tests pass so far. I'll keep going.

Ok, bit of a blocker - all dependencies except Nustache support .NET Standard (project seems to be somewhat dead - jdiamond/Nustache#121). I will see if I can find a compatible alternative (the project owner suggests stubble).

Wow, OK, yak-shaving time. There is _no_ Mustache implementation currently compatible with .NET Standard (any version!). Looks like I'll have to create a .NET Standard port of Nustache (or similar).

Anyone else who'd like to help - now's the time to pitch in :)

Actually, let me see if it'll still run on .NET Standard 2.0 first (I get the usual NU1701 but it may still work correctly).

Ok, a more serious blocker: dotnet/roslyn#17968. There's currently no MSBuildWorkspace for .NET Standard. I might have another poke around the OmniSharp source code to see how hard it would be to create an interim workaround for this.

Have ported everything except CLI, tests, and Microsoft.DocAsCode.Metadata.ManagedReference for now. Will have a think about what it would take to make Microsoft.DocAsCode.Metadata.ManagedReference work on .NET Standard but it sounds like this library in particular may be a bit trickier to port.

Probably have a solution for Microsoft.DocAsCode.Metadata.ManagedReference:

https://gist.github.com/tintoy/76b48591e2a34429c1f5c02556b8b4d2#file-program-cs

Essentially, we can use an AdhocWorkspace and populate it using the MSBuild engine to examine the project's properties and items; a slightly-less-sophisticated version of what MSBuildWorkspace does.

This may not work for _every single_ project out there (e.g. if a project has <Compile> items that are added by custom tasks that can only run on the full .NET framework because they're AppDomain-isolated) but it should be fine for 95% of use-cases (chances are, the existing metadata extractor doesn't work for 100% of projects right now anyway).

@vicancy - before I go any further on this can I get some feedback from you on whether you find this approach acceptable?

@tintoy Sorry for late response. I was on vacation and am back now. I will take a look at it today.

@vicancy no problem, take your time - I've got plenty of other stuff to keep me busy :)

@tintoy Thinking of changing from Mustache to Handlebars, https://www.nuget.org/packages/Handlebars.Net/ suports .NET standard

Nice - I totally forgot about Handlebars; how compatible is the syntax between the 2? It's been ages since I used Handlebars, but I seem to remember it's basically a superset of Mustache...

@tintoy It generally compatible with Mustache, the main difference is that it does not search up when context does not found, which is exactly what we expect. There may be other differences that leads to a breaking change (which is my main concern) so I need more time to test before switching. ๐Ÿ˜ข

Yeah, I see what you mean, and it looks like there are only a couple of tests for the template processor at the moment. Still, that's the great thing about Xunit theories - write 1 test and then just keep adding test data ๐Ÿ˜Ž

@tintoy with the 95% support, is this <Comiple case the only case that the AdhocWorkspace does not support?

It can support it, we just have to use Microsoft.Build.Evaluationto evaluate the Compile item group :) I can whip up an example if you like

(just may not work for _every_ project e.g. the exceptions listed above)

@vicancy - this demonstrates evaluating the <Compile/> items and adding them to the workspace.

Hi @tintoy

{{#summary}}
{{summary}}
{{/summary}}

So I don't have a decent solution for Nustache project migrating to netstardard .. ๐Ÿ˜ฟ any idea?

cc @vwxyzh @superyyrrzz

Do you think it would be better to add a comprehensive test suites to docfx project before we moving to AdhocWorkspace

Yep, I agree this would be very worthwhile :)

As for Nustache, we might need to wind up working (or working with someone) to port an existing implementation?

(I have a couple of projects I use for testing MSBuild Project Tools that we can use as well)

Nustache looks like it would be pretty easy to port, BTW.

@vicancy - which bits of Nustache are used by DocFX? I just ported Nustache.Core, Nustache.Compilation, and Nustache.Core.Tests to netstandard2.0 / netcoreapp2.0 in less than 15 minutes and they're fine apart from a small fraction of the unit tests that rely on a library (DynamicExpresso) that itself has not been ported to netstandard.

No code changes required, BTW, except to the unit tests (upgraded to NUnit 3, so some attribute / property names in the NUnit framework have changed).

BTW, around 4 (out of 285) of the Nustache unit tests don't pass, but they don't pass in the original project either. I had to disable one test because it alters a static global that breaks around 20 other tests.

If I can get you a set of packages or a copy of the ported code would you be able to see if it works when plugged into existing DocFX tests?

@tintoy we are using Nustache.Core. I created a https://github.com/jdiamond/Nustache/issues/129 asking them about the plan, looks like that project is silent since Oct 10, 2016

We can test it with a package of ported Nustache.Core

Ok I'll create a myget feed with packages you can use to test.
On Mon, 23 Oct 2017 at 6:32 pm, Liangying.Wei notifications@github.com
wrote:

We can test it with a package of ported Nustache.Core

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/docfx/issues/1963#issuecomment-338571650, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABkezCRM44eiNYGsmLCB0aZTwoCJb6foks5svEEegaJpZM4O4ZWH
.

@vicancy - you can pull from https://www.myget.org/F/nustache-netstandard/api/v3/index.json (built against netstandard2.0).

@tintoy If you'd like to open a pull request on Nustache with your changes i'd be happy to look them over and get an official release out

Thanks @Romanx :)

I may need to first submit a PR to an upstream project (DynamicExpresso) used by some of your tests since that doesn't support .NET Standard yet either. But as soon as I can get that done I'll submit the PR. In the meanwhile I can at least fork the original repo for Nustache and apply my changes there (at the moment it's all in a local repo only).

Ok - initial port is sitting in https://github.com/tintoy/Nustache/tree/feature/netstandard. Would you mind having a poke-around the project to see what you think before I open a PR, @Romanx?

There are a couple of tests (around Sections) that fail, but as far as I can tell, they failed before the port, too (had to upgrade to a more recent version of NUnit, among other changes).

@tintoy I'll have a look later today and see whats up with those tests.

@tintoy I just checked out the repo. Seemed to work when I ran all the tests. Which are you finding don't seem to work?

@Romanx - was that on the feature/netstandard branch? These ones fail or are inconclusive / skipped for me:

failing tests

@tintoy it's quite probably I derped and wasn't on the right branch. Let me confirm again ๐Ÿ‘

@tintoy I've worked out what the change was that caused the test failures. One is that the changing to use Json.Net returns the object in a different format to the JavascriptSerializer and the other is that originally it was pulling the data from the submodule specs. After refactoring the folder structure the pathing was off so you added the specs to the repo which are now different to the submodule which is where the "new" failure come from as the submodule hasn't been updated in awhile.

I'm pretty sure i've got a fix for the object format and i'm just working on regenerating the strongly typed objects from the spec, Would you like me to open a pull request to your repo when i'm done?

@Romanx - thanks, that'd be awesome!

Hi @Romanx Any progress ๐Ÿ˜„ ?

Hi @tintoy I'd like to move forward with the AdhocWorkspace approach. Theoretically it can resolve #1752 & #138 if I am understanding correctly, is it? And after this approach, I plan to setup some CI to test it under different environment.
It would be fantastic if you could create an PR with this approach. ๐Ÿ˜„

Ok - I'm about to go camping for the weekend but I'll get onto it early next week :)

@vicancy We're having issues with the changed tests not working on @tintoy's environment and working on mine. Hoping to find some time this weekend to get to it

@vicancy have a look at 6864ff239daac7bbc54c545a07811c112df182da - that should give you an idea of the scope of changes I have to make (it compiles but I haven't tried any of the tests yet).

Actually, I'm thinking I might create extension methods for AdhocWorkspace to emulate the old OpenProjectAsync APIs. What do you reckon?

Turns out AdhocWorkspace is mutable and therefore may not be thread-safe. Will investigate :)

Ok turns out it's thread-safe.

@vicancy would you mind pulling down the latest code from my fork and running the tests? There are a couple I don't understand well enough to work out why they are failing... It's the feature/netstandard branch.

@tintoy Sure, I will take a look

Hi @tintoy Can build pass with the feature/netstandard branch? Mine can't pass build, looks like System.Runtime.Remoting.Lifetime; is not available in netstandard.
image

Which project was that? I didn't see any build errors but I was just running tests from within VS. I'll have a look at that first thing tomorrow, should be easy to fix either way.

I haven't tried porting the main executable yet, only the libraries it depends on. The exe will take some more work because it currently relies on Appdomain but I do have a proposed design that will work cross-platform. In the meanwhile, would you mind trying to run the unit tests ignoring that executable build error?

BTW, am I correct in assuming that use of Appdomains is mainly to control base path for loading assemblies? If so, AssemblyLoadContext is the replacement.

@tintoy AppDomain is to isolate assemblies loaded from plugins. We are thinking of creating a new process instead.

Yep that'd be the way :)

They can communicate over STDOUT / STDIN (have code that does this in an
LSP language service that might be helpful). Were you able to run the tests
if you ignore the build error in that project?

On Thu, 30 Nov. 2017, 4:14 pm Liangying.Wei, notifications@github.com
wrote:

@tintoy https://github.com/tintoy AppDomain is to isolate assemblies
loaded from plugins. We are thinking of creating a new process instead.

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/docfx/issues/1963#issuecomment-348084783, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABkezLKhN6WsValNir-cVI-KBIRe7ac5ks5s7jmngaJpZM4O4ZWH
.

@tintoy I changed docfx and docfx.test projects back to use base.props and can pass build now. I am running test and meet some runtime assembly loading errors. I am looking into it.

Hi @tintoy I also meet several kind of ut failures with your changes. However that branch is quite behind the latest branch and contains a lot of changes. I'd like to make small moves step by step for easy debugging and code review, so I am cherry-picking your changes and sending out PR for every commit.

@vicancy - I recently stumbled across Buildalyzer, which seems to have fairly full-featured support for building a Roslyn AdhocWorkspace from project files in most formats:

image

Might be worth considering?

Hi @tintoy thank you for the info, I will take a look. With a first glance, it looks like also dependent on msbuild.dll to load and parse the project, so I am now a little confused why we not use MSBuildWorkspace, it is from https://www.nuget.org/packages/Microsoft.CodeAnalysis.Workspaces.Common/ and has a netstardard1.3 version...

I think MSBuildWorkspace is in the package Microsoft.CodeAnalysis.Workspaces.Desktop, which does not target .NET standard (yet)?

AdhocWorkspace is in Microsoft.CodeAnalysis.Workspaces.Common though.

@tintoy Oh yes, netstardard1.3 does not contain Microsoft.CodeAnalysis.Workspaces.Desktop assembly

Close as v2 is not likely to support it. v3 will.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ntvuong1709it picture ntvuong1709it  ยท  4Comments

mgregory22 picture mgregory22  ยท  3Comments

xxcuratorxx picture xxcuratorxx  ยท  3Comments

Shazwazza picture Shazwazza  ยท  5Comments

eberjoe picture eberjoe  ยท  3Comments