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

Feature request - Option to update user global packages folder automatically after successful pack #9891

Closed
thesushil opened this issue Aug 10, 2020 · 10 comments
Labels
Functionality:Pack Triage:NeedsTriageDiscussion Type:Feature WaitingForCustomer Applied when a NuGet triage person needs more info from the OP

Comments

@thesushil
Copy link

thesushil commented Aug 10, 2020

NuGet product used: NuGet.exe | VS UI
NuGet version 5.6.0.6591
VS version 16.6.3
OS version Windows Server 2019

  1. Setup 2 solutions each with a project so that one project has a package reference to the other. Project A depends on Project B via nuget package reference. Set GeneratePackageOnBuild to true in Project B.

  2. Make changes to project B and build it.
    Then go back to Project A and rebuild it. The previous change in project B is not reflected in project A.

Expectation: The change in project B should reflect in project A so I can test it and finally check in.

Suggested feature:
When the nupkg is generated for project B after successful build, it should (optionally) update the nuget user cache as well, overwriting if the same version already exists.

Local package source option doesn't work either as it would require increasing version every time project B is changed. If version is not increased it would use the older code of the same version from the nuget cache. After the successful testing, I would normally check in and the package version would be increased.

Keeping both projects in the same solution is also not a good idea, as that would mean all the projects referencing project B should be in the same solution as B which defeats the purpose of nuget reference.

Workaround:
We ended up implementing a custom target that deletes the package in the nuget cache and updates it with the newly built pack. It would be nice to have this feature built in.

@donnie-msft
Copy link
Contributor

donnie-msft commented Aug 17, 2020

NuGet is designed around unique version numbers, so trying to avoid that may prove difficult.

My initial thought here is to consider using Pre-Release version numbers for your Project B packages until releasing them. This would work without using pre-release versions, but if you're wanting to avoid generating many "official" version numbers, it's worth considering.
Then, Project A would use a floating reference (either for pre-release or for official versions), meaning it will always take the latest pre-release package available.

@zkat may have more specific guidance.

@donnie-msft donnie-msft added the WaitingForCustomer Applied when a NuGet triage person needs more info from the OP label Aug 17, 2020
@donnie-msft
Copy link
Contributor

You may also want to review, comment and/or upvote this issue: #6579

@thesushil
Copy link
Author

thesushil commented Aug 17, 2020

I think version numbers is not a problem here, unless I am missing something. After the successful pack, it would delete the package in the cache if the same version already exists and then add the new package to the cache. Version number would come from the project, parameter, etc. as usual.

Using pre-release doesn't seem the right solution, as I am not releasing to anyone else, it's for my own testing, just that the testings are happening in other solutions. It would also increase the build time as the package has to be copied to and from the local feed in addition to the cache after every change.
Using a floating version does solve the problem of constantly requiring to update the version in the consuming projects. But I think going the pre-release route is unnecessarily chatty and slow.

I also commented and upvoted in the issue: #6579. Looks like we're trying to solve the same problem.

@nkolev92 nkolev92 changed the title Feature request - Option to update user cache automatically after successful pack Feature request - Option to update user global packages folder automatically after successful pack Aug 18, 2020
@nkolev92
Copy link
Member

I think version numbers is not a problem here, unless I am missing something. After the successful pack, it would delete the package in the cache if the same version already exists and then add the new package to the cache. Version number would come from the project, parameter, etc. as usual.

There's a slight correctness challenge with just replacing the package content in the global packages folder is that restore need to run again.

In particular, a restore for a given project needs 2 things from a package:

  • nuspec for dependencies and metadata
  • the file list for that specific package.

The file list is used for compatibility selection, and the file list is used to generate the references that'll be provided to the compiler.
The nuspec is used for dependency walking.
Hot-swapping the content will not work unless restore is taught to look at the global packages folder to do the compat selection again.

Now, the next logical argument is, how often would this happen?
And that's a great argument, but the consequences are pretty hard to understand :)

Finally, the global packages folder can be controlled on a project level too.
From a gesture perspective, I'd probably prefer for the consumer to control this rather than the packaging project.
It allows things to work through feeds instead.
Otherwise, you can easily end up where projects build locally, because the gpf was prepopulated, and not work on the CI.

@thesushil
Copy link
Author

@nkolev92 could you give an example of incompat scenario? We've been running this for a long time and haven't seen any issue, or maybe we have but we don't know.
There could be other issues beside this, that's why I am requesting this feature to be optional, like with a new parameter UpdateCache.

@itsmedeep
Copy link

Nice work. Keep it up

@nkolev92
Copy link
Member

@thesushil

  • Changes in metadata for content files is one example.
  • Changes in file count such as additions/subtractions of files.
  • Changes in dependencies, framework references, framework assemblies.

@aortiz-msft
Copy link
Contributor

Closing as duplicate of #6579

@nickhoeferpickpro
Copy link

I have been spending the last couple days trying to figure this out. I did something like this to achieve a similar effect.
I borrowed the idea from @thesushil

<Target Name="DeleteLocalCache" BeforeTargets="Pack">
  <RemoveDir Directories="$(NugetPackageRoot)$(PackageId.ToLower())\$(version)" />
  <Message Text="Cleaning $(NugetPackageRoot)$(PackageId.ToLower())\$(version)" />
</Target>

<Target Name="UpdateLocalCache" AfterTargets="Pack">		
  <Message Text="creating diretory $(NugetPackageRoot)$(PackageId.ToLower())\$(version)" Importance="high" />
  <MakeDir Directories="$(NugetPackageRoot)$(PackageId.ToLower())\$(version)" />
  <Message Text="copying file $(PackageOutputPath)$(AssemblyName).$(version).nupkg" Importance="high" />
  <Copy SourceFiles="$(PackageOutputPath)$(AssemblyName).$(version).nupkg" DestinationFolder="$(NugetPackageRoot)$(PackageId.ToLower())\$(version)" />
		
  <Exec Command="tar -xf $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\$(AssemblyName).$(version).nupkg -C $(NugetPackageRoot)$(PackageId.ToLower())\$(version)" />
  <Exec Command="certutil -hashfile $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\$(AssemblyName).$(version).nupkg SHA512 &gt; $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp1.txt" />
  <Exec Command="more +1 $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp1.txt &gt; $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp2.txt " />
  <Exec Command="powershell Get-Content $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp2.txt -First 1 &gt; $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\$(AssemblyName).$(version).nupkg.sha512" />
  <Exec Command="del /f $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp1.txt" />
  <Exec Command="del /f $(NugetPackageRoot)$(PackageId.ToLower())\$(version)\temp2.txt" />
</Target>

If anyone knows a more elegant way to handle this, I'm all ears. Changing version numbers each time just for local development is just silly. semver is great and everything but we shouldn't be forced to adhere to it just for the sake of purity because doing so results in dirty hacks or workarounds.

I think #7092 is related.

@gioce90
Copy link

gioce90 commented Dec 30, 2024

Hi @thesushil @itsmedeep @nickhoeferpickpro , I’ve faced similar issues in the past when working with NuGet packages. As I mentioned #6579 (comment), I created a tool to address these problems.
I’ve now decided to make my solution public by releasing a package called NuJet (https://github.com/gioce90/NuJet). It enhances the inner-loop development and testing process for NuGet packages, especially in local workflows.

Feel free to check it out—I’d love to hear your feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Functionality:Pack Triage:NeedsTriageDiscussion Type:Feature WaitingForCustomer Applied when a NuGet triage person needs more info from the OP
Projects
None yet
Development

No branches or pull requests

7 participants