1

When creating a nuget package and setting up the nuspec file, is there a way to only add the file if it does not already exist?

I don't want the file to be replaced on every update.

I have seen this answer, but it doesn't seem to be complete.

Let's say I want a file called "example.css" to be included in a new project, but only on first install, how can i achieve that?

In my nuspec file i will have this line:

<file src="css\example.css" target="content/css" />

But it overwrites anything that is there.

Quintonn
  • 770
  • 8
  • 29
  • Overwrite the content file when you update the nuget package is designed by nuget. You have to create install.ps1 powershell scripts to check if the project have the that file exist and prevent nuget overwrite it. – Leo Liu Sep 19 '18 at 09:45
  • Aagin, since you do not want to overwrite this `.css` file when you update you nuget package, why not include this file separately in a Nuget package? This .css file will not be rewritten in the new nuget package when you upgrade your original package. – Leo Liu Sep 19 '18 at 09:50
  • @LeoLiu-MSFT, yes how do i do that with the install.ps1 file? I couldn't get that working with the linked code. What is your second suggestion? I make a separate nuget packge for the once of .css file? – Quintonn Sep 20 '18 at 06:11
  • After a long period of pain, I found out that we could not use the install.ps1 file to resolve this issue, you can check below answer for details. If I am wrong, please let me know for free :), willing to accept any comments. – Leo Liu Sep 20 '18 at 08:53
  • Hi @LeoLiu-MSFT, my experience also showed the install.ps1 was being run too late. A possible solution would be to store the target files `eg: example.css` in a different location like a `lib` or `package` folder. Then we can use the install.ps1 file to check if the target file exists in the final location and if it does not, we copy it from the lib folder to the ideal target location. But to me this is not something easily re-usable and is very hacky. I'm sure i've seen other nuget packages achieve this, it must be possible. – Quintonn Sep 21 '18 at 07:22
  • `I'm sure i've seen other nuget packages achieve this, it must be possible.` -Do you remember the ID of that package? If there is such a package, we can parse install.ps1. Sorry, I have not encountered a similar package. – Leo Liu Sep 21 '18 at 07:35

1 Answers1

0

How to only add a file if it doesn't already exist using Nuget and the nuspec file

I have been suffering for this issue since yesterday. At first, I have the same idea as the accepted answer in the link provided in your question, using install.ps1 in the Tools folder with function that if a example.css file already exists, nuget update will not overwrite it. So I tried to create this install.ps1, but I failed.

That because:

  1. The file install.ps1 runs after the package is installed in a project.
  2. Update package will uninstall the old version package including contents.

Detailed for the reasons 1:

According to the document Run PowerShell script during NuGetpackage installation and removal:

Install.ps1 runs when a package is installed in a project.

We could get the hidden information, file Install.ps1 runs after package installed.

In order to verify it, I have created a test sample nuget package with .nuspec:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>MyTestPackage</id>
    <version>1.0.0</version>
    <authors>Tester</authors>
    <owners>Tester</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2018</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
  <files>
    <file src="bin\Debug\MyTestPackage.dll" target="lib\net462" />
    <file src="css\example.css" target="content\css\example.css" />
    <file src="Tools\install.ps1" target="Tools\install.ps1" />
  </files>
</package>

And the content of install.ps1:

Start-Sleep -Seconds 20
write-host "Hello world!"
Start-Sleep -Seconds 5

Then I added my MyTestPackage.nupkg to the test project, I found that the content added to the project before install.ps1 was executed.

Then I created a version 2.0.0 with different content in the example.css file (Just for testing), then I updated the package from 1.0.0 to 2.0.0, the example.css wil be replaced before install.ps1 was executed:

enter image description here

When we update the nuget package, nuget will update the package and overwrite contents first, then executed the file install.ps1. So it seems we could not use the file install.ps1 to prevent NuGet overwrite the file example.css file.

Detailed for the reasons 2:

If you pay attention to the upgrade process in the animation above, you will find that when upgrading the package, nuget will remove the package including contents first, then re-install the new version package. So, nuget will remove the package and its content first when we update the package, the result of the conditional judgment file existence is always negative. NuGet will add the .css file in the new version nuget package to the project.

If you have to prevent nuget overwrite this/those file(s), As workaround for this issue, you can include this/those file(s) in a new nuget package, this/those file(s) will not be overwritten in the new nuget package when you upgrade your original package.

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135