OldSquirrelForWindows icon indicating copy to clipboard operation
OldSquirrelForWindows copied to clipboard

Shimmer needs to handle Profiles and PLibs

Open anaisbetts opened this issue 12 years ago • 11 comments

It Gets Worse

Here's the tricky part, with the invention of PLibs, we actually don't know what assembly they're actually referencing - NuGet itself is deterministic about it, but there's no reason why someone couldn't add a reference to a different assembly by-hand. This problem also happens with NuGet packages that ship 2.0-3.5, or 4.0-4.5 DLLs in the same package (i.e. a .NET 3.5 app could very well be using the 2.0 DLL).

Meaning, we actually need to scan the target assemblies to figure out what they're referencing. Cue the Sad Trombones.

anaisbetts avatar Mar 19 '13 17:03 anaisbetts

Paging @dsplaisted to this thread. Paging @dsplaisted to this thread. sirens wailing

shiftkey avatar Mar 19 '13 17:03 shiftkey

I don't think this is a bug in PLibs, it would still happen even if PLibs didn't exist, it just is way more common now

anaisbetts avatar Mar 19 '13 17:03 anaisbetts

Nah, just wondering if Daniel has any input on this.

shiftkey avatar Mar 19 '13 17:03 shiftkey

@dsplaisted here, reporting for duty :)

Can you explain the context here? I kind of know in general what Shimmer does, but when do you need to know what an assembly references and how do you use that information?

dsplaisted avatar Mar 19 '13 19:03 dsplaisted

I believe Microsoft.CCI allows you to look at the physical references in the Assembly. (I don't remember if that's functionality was added or they're just using it from .NET offhand).

wwahammy avatar Mar 19 '13 19:03 wwahammy

@dsplaisted So, the idea here is that we're trying to take a NuGet package that has a bunch of dependencies, and create a flattened NuGet package (i.e. one that has no dependencies, more details here).

But the tricky bit is, we also need to strip out DLLs that aren't actually being referenced by the main project. Things like WP8 profiles are easy, but determining which DLL GitHub.exe is actually being built against (i.e. is it using the Net40, Net35 or Portable+Net40+Win8 DLL for a particular package), is Tricky™

At the moment, my solution is to start cutting into the actual assemblies using Cecil, but even the definition of an Assembly Reference is sometimes ambiguous (i.e. there are 9 versions of Microsoft.Threading.Tasks that are definitely different, yet have the same FullName).

anaisbetts avatar Mar 19 '13 19:03 anaisbetts

Possible Solution

  1. Take the original NuGet package
  2. Instead of blindly recursively merging dependencies as described in the spec, determine the profile of the top-level NuGet package...
  3. ...then use the same algorithm NuGet would use to add the reference, to determine which platform folder to keep.

Thoughts? This means if someone manually added references to a different DLL via "Add Reference..." to the packages folder, they're screwed, but I'm not sure we can do better without analyzing a csproj file.

This also means that this janky code in UpdateManager goes away as well, since we simply just copy all of the DLLs verbatim.

anaisbetts avatar Mar 19 '13 19:03 anaisbetts

The possible solution of starting with the top-level profile and using NuGet's algorithms to determine what DLLs are actually referenced sounds like the right solution.

You should probably be able to use those algorithms directly by referencing NuGet.Core instead of re-writing them yourself.

Also, once you've flattened all the NuGet references, you should probably inspect the assembly references of the EXE and DLLs in the root package, and see if there are any references that weren't satisfied by NuGet packages. Those would be the ones where the project was referencing another assembly without using NuGet.

dsplaisted avatar Mar 19 '13 19:03 dsplaisted

You should probably be able to use those algorithms directly by referencing NuGet.Core instead of re-writing them yourself.

Yep, Shimmer already uses NuGet.Core pretty heavily so that'll definitely be my plan.

Those would be the ones where the project was referencing another assembly without using NuGet.

Not a bad idea for verification later in the build, where we have a notion of a build directory / project (in Shimmer.Core, we only know about NuGet packages and assume you created the input package correctly)

anaisbetts avatar Mar 19 '13 20:03 anaisbetts

I am experiencing this issue when referencing Akavache: I have a .Net 4.5.1 WPF application, but instead of having Akavache.dll from lib\net45, I end up with the one from lib\Portable-Net45+WinRT45+WP8. Is there any workaround I can use?

dchaib avatar Feb 18 '14 22:02 dchaib

This might be because our version of NuGet is behind. I'll investigate.

shiftkey avatar Mar 23 '14 02:03 shiftkey