Solution Only Packages vs. Normal Packages

Oct 9, 2010 at 6:55 AM

Hi folks,

I'm hoping someone on the core team can answer this one. I'm hacking around in the code writing a patch for the following work item:

  • [workitem:allow meta packages (no files, only dependencies)|180]

It has gotten a few votes and I _thought_ that it would be a fairly quick fix just to get my feet wet as a contributor. I've pretty much identified what I would need to do to make it work but it has left me with more questions than answers, so before I go and create a fork and implement the patch I wanted to ask some questions for clarification about the general design of the code-base.

If you take a look at the "InstallPackageCmdlet" class in NuPack.VisualStudio you can see the the "ProcessRecordCore" method which is part of the PowerShell plumbing. Within that method a boolean flag is set called "isSolutionLevelPackage". The implementation of the code that sets this flag basically determines that a solution level package is any package that doesn't contain content (i.e. no \lib folder). Based on this flag the code calls "InstallPackage" on a "PackageManager" instance (solution level packages), or "AddPackageReference" on a "ProjectManager" instance (normal packages).

The InstallPackage routine ultimately ends up just unpacking the files, whereas the AddPackageReference unpacks the files and adds assembly references to the projects. From an API point of view I think having AddPackageReference and InstallPackage really should be rolled in together (or one is called downstream from the other. I think that there should really only be one entry point into the package management space from the Cmdlet (from a good abstraction point of view) and I also think that it isn't the Cmdlet's job to make the decision about what is a solution package and how it treats it. The fact that a solution package is defined as one that has no content will ultimately make it difficult to define meta packages.

The <dependency />attribute may also need to be modified to define how you want that dependency to be handled, for example:

  <dependency installBehaviour="addReference|install" />

Thoughts?

Developer
Oct 9, 2010 at 7:03 AM

I think the way to fix this would be to alter our check for IsSolutionLevelPackage by not checking for HasProjectContent but by some other heuristic maybe tools folder with ps1 scripts? (that's the purpose anyways). The second part of the fix would be removing the fail if a package has no project content since it's harmless. I don't think meta packages are anything special and in fact this used to work until we implemented solution level packages.

Coordinator
Oct 9, 2010 at 7:06 AM

How about: a solution only package is a package that has no content, but does have a tools folder with at least one file. I don’t think we should require a .ps1 file in there because what if the file is a .exe or a .bat?

Oct 9, 2010 at 7:29 AM

Architecturally, I agree with Mitch that it shouldn't be the CmdLet's decision to treat a package as solution level or not.  This should be pushed into the Core.  The decision is sort of a heuristic, and maybe taking the Tools folder into account makes sense (though it's on the dirty side :) ).

I'm hoping that we don't need this installBehavior on the <dependency>, as hopefully the decision is intrinsic to the package content.

But an interesting question is whether the mode can switch back and forth.  My take is that the installation of a Project Level package can trigger the installation of a Solution Level package.  However, the converse seems dubious.  But maybe we shouldn't block it.  i.e. anytime a package needs to be installed (either the initial one or via a dependency), we would go through the heuristic to decide whether it's Solution or Project level.

Developer
Oct 9, 2010 at 7:42 AM

First off solution level is a VS concept not a core concept so by "core" we mean the VS assembly. The general solution is we need *some heuristic* to determine if a package is a solution level package. We should remove all knowledge from the core about packages that have project content and just let it go through.