5

I am looking at nuget for improving automatic handling of dependencies (both internal and third party) during development.

A long as you develop through the CI Build Server, all is good:

  1. get latest source for A and B, where B depends on A
  2. fix bug in A
  3. build A
  4. check into source control
  5. CI Build Server initiated
  6. new nuget package is created and placed in corporate repository
  7. build B (which will get the updated A package)
  8. run B to verify that the bug in A was fixed n. repeat n times

However, I'm wondering if it is possible to work locally as a single developer, without having to wait for the CI Build Server to produce a new package?

Nuget has a feature Package Restore, which will download all dependencies automatically on build. You can also list the repository order that the Package Restore should look for packages.

If the workflow could become:

  1. get latest source for A and B, where B depends on A
  2. fix bug in A
  3. build A
  4. (building creates a local nuget package)
  5. run B to test the (resolved) bug in A (should now use our local nuget package, not local repository)
  6. ...repeat n times
  7. check into source control
  8. CI Build Server initiated
  9. new nuget package created in corporate repository

Is this possible using Visual Studio, MSBuild, a CI Build Server and nuget? I'm especially interested in the making of local packages while developing locally.

Note that I have native projects, although except the generation of nuget package post-build, this would be a workflow that I hope should work for both C# and C++ projects.

meastp
  • 682
  • 1
  • 7
  • 15
  • same problem here, found a solution that sorta works but Nuget does not play nice with it so nop. back to hooking / unkooking dependencies manually. Works fine for a few but we have them by the hundreds, imposing this grantees a programmer's pitch fork revolution against the build system and it's masters ! I"ll keep looking and post my findings here if any (was gonna ask it myself !) – Newtopian May 22 '14 at 22:37
  • @Newtopian: Cool, keep us posted, please :) Perhaps you could elaborate what you have tried, so we don't have to? :) – meastp Jun 20 '14 at 10:45
  • I would do this for local development without CI Server: https://stackoverflow.com/a/63485994/1662819 – Bahaa Aug 19 '20 at 14:53

2 Answers2

3

The solution I have now, though far from ideal, is what I could figure out works best. Oh! and it is a work in progress so it WILL change in the coming weeks/months as I figure out how to get around the kinks.

I mostly have to deal with managed DLL right now but I do have some native code and worst, multi-platform native code to deal with eventually.

Create a local repository, basically just a folder and configure it in your list of nuget feeds.

Then I created a task (MSBuild) that will package the project and output it in the local repository's root folder. Make sure the version of your package is always increasing. Presently I do this manually by editing the assembly version.

Once built, update your other projects that reference it, I usually do this though the package manager console (update-package).

Each projects that was updated, bump up their version rinse lathe and repeat until you get to your top-most project (the actual program).

Once everything is nice and good and you are ready to commit then the build system should do it's own packaging and send it to your official repository.

The Good

  • No clogging of the repository and build system with intermediary development versions, that garbage remains (as it should) local.
  • Local repos are super easy to set-up, can even be done without changes to VS though the global nuget config.
  • This is friendly to both paradigms of package recover or checking-in packages with the project. That said I would recommend not checking in the packages you built locally but rather one that was committed to your local repository ideally through the build system. What's built local should remain local.

The Bad

  • Still much more complicated than just adding projects to a solution.
  • The deeper (or wider) your dependency tree the bigger the pain.

The Ugly

  • Makes some native nuget behaviors quite quirky and annoying :
    • Update operation takes forever if your VS is connected to a version system (perforce for me). I hear they "solved" the problem, would hate to see how it was before if it was worst that it is now !
    • Having nuget change non-code reference back to never copy is a major pain.

If Only

  • Configure the desired state of a content dependency (copy always, never or newer) directly from the nuspec and be done with it ! (oh and same story with ClickOnce content status include, exclude etc)
  • Make the update operation quick, 2 minutes for a dozen project is just insane, especially if the ultimate goal is to manage 500+.
  • Perhaps a hybrid mode where locally we work with projects inclusion but the build system would work with nuget dependency (and build them if necessary)
  • If you are to parse the project do follow MSBuild parsing rules and honor the conditional statements. There are still issues I have yet to figure out like how to manage multiple branches of the code in the repository. How to handle version conflict further up the food chain. In a large project (ultimately we have to bring 500+ separate projects together in a single application executable, conflicts are expected).

I would love to bring all the goodness of sane dependency management à la Maven but thus far I did not find nuget to be mature enough to even think of proposing it to the dev team.

Newtopian
  • 7,543
  • 4
  • 48
  • 71
2

Certainly. In our solutions, NuGet parks the libraries in the "packages" directory of the solution's hierarchy which is ultimately kept in TFS. This allows for complete solution check-outs that includes the required libraries. If it's your intention to update the libraries normally provided by NuGet, you'll need to update the dependent projects' references to point to the project containing the updated code normally provided by the NuGet process.

Prior to checking-in your regular solution work (not the NuGet related libs,) make sure the solution's NuGet libs are up to date, and the references in the solution point back to the NuGet installed libs. Of course, you'll check-in and fetch the NuGet related libs beforehand.

bvj
  • 3,294
  • 31
  • 30
  • Thanks for the quick answer. I forgot to mention that it's C++. I don't want to check binary files etc. into source control, and I was hoping nuget maintained a local cache for me, making the proposed workflow possible. We also only keep projects in source control - not solutions. Is it still possible? – meastp Nov 29 '13 at 15:52
  • Understood. I had C# on the brain. There is a "NuGet for C++" which I haven't used. Of course, the include/lib paradigm is more flexible for C/C++, so I'm inclined to say "yes". FWIW, I typically launch/build C/C++ projects each with their own environment settings/variables. So when you're maintaining the NuGet libs your inc/lib could point to it; otherwise, point to the locations established for the team which points to the distributed NuGet binaries. HTH. – bvj Nov 29 '13 at 16:26
  • I was hoping this would be possible with both C# and C++. I have discovered the Package Restore feature: If I list my local repository first, and the corporate-wide repository second, shouldn't this work automatically? i.e. Package Restore picks up my newly built package A from my local repository. – meastp Nov 30 '13 at 20:22
  • I have updated the question with more details, hopefully it is clearer what I want to achieve (and how). – meastp Nov 30 '13 at 20:42
  • I don't have anything else to add at this time, but it's a great workflow question. Regarding the Package Restore feature, does this occur only if the packages are missing, or can it be forced to overwrite existing settings that might exist on the build server? – bvj Nov 30 '13 at 23:58
  • The Package Restore feature only downloads missing packages, and does not touch anything else (such as updating to the latest version in packages.config). If one wants to update to the latest version of the package(s), that needs to be done independently (and this would be required for the workflow I propose in my question) – meastp Dec 02 '13 at 12:13
  • It'd be nice if nugget could handle this automagically though. It is possible through some clever MSBuild construct to either point to the nuget dependency or to the project. Unfortunately the magic does't stick as nuget VS integration trashes it when performing update, installs or deletes of that particular dependency in the project. This said the question is relevant regardless if one uses restore workflow or committed dependencies. With hundreds of dependencies I cannot move to Nugget until I have a simpler workflow – Newtopian May 22 '14 at 22:35
  • Is it possible to perform the Package Restore manually, as part of an MSBuild construct? Perhaps disable the VS feature and doing it manually could work? – meastp Jun 20 '14 at 10:48