1
votes

I created a NuGet package using the NuGet Packager project template for VS2013. I'm trying to copy the DLL files in the bin\CONFIGURATION folder into the lib folder of the nupkg file using Replacement Tokens in the Package.nuspec file.

When building the solution in Visual Studio, I'm getting the following error in NuGet.log:

[INFO] : Attempting to build package from 'Package.nuspec'.
[ERROR] : System.InvalidOperationException: The replacement token 'configuration' has no value.
[ERROR] :    at NuGet.Preprocessor.ReplaceToken(String propertyName, IPropertyProvider propertyProvider, Boolean throwIfNotFound)
[ERROR] :    at NuGet.Preprocessor.Process(Stream stream, IPropertyProvider propertyProvider, Boolean throwIfNotFound)
[ERROR] :    at NuGet.Manifest.ReadFrom(Stream stream, IPropertyProvider propertyProvider, Boolean validateSchema)
[ERROR] :    at NuGet.PackageBuilder.ReadManifest(Stream stream, String basePath, IPropertyProvider propertyProvider)
[ERROR] :    at NuGet.PackageBuilder..ctor(String path, String basePath, IPropertyProvider propertyProvider, Boolean includeEmptyDirectories)
[ERROR] :    at NuGet.CommandLine.PackCommand.CreatePackageBuilderFromNuspec(String path)
[ERROR] :    at NuGet.CommandLine.PackCommand.BuildFromNuspec(String path)
[ERROR] :    at NuGet.CommandLine.PackCommand.BuildPackage(String path)
[ERROR] :    at NuGet.CommandLine.PackCommand.ExecuteCommand()
[ERROR] :    at NuGet.CommandLine.Command.ExecuteCommandAsync()
[ERROR] :    at NuGet.CommandLine.Command.Execute()
[ERROR] :    at NuGet.CommandLine.Program.MainCore(String workingDirectory, String[] args)

The relevant snippet of Package.nuspec:

<package>
  <files>
    <file src="bin\$configuration$\$id$.dll" target="lib\net451\" />

I can package this from the command line using this command just fine:

c:\Path\To\Project> nuget pack -Properties Package.nuspec

So I did a little playing around in NuGetPackage.ps1 and found this section:

# Create symbols package if any .pdb files are located in the lib folder
If ((Get-ChildItem *.pdb -Path .\lib -Recurse).Count -gt 0) {
    $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Symbol -Verbosity Detailed")
    $packageTask.Start() | Out-Null
    $packageTask.WaitForExit()

    $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
    $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_}) 
    Write-Log $output
    Write-Log $error Error

    $global:ExitCode = $packageTask.ExitCode
}
Else {
    $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Verbosity Detailed")
    $packageTask.Start() | Out-Null
    $packageTask.WaitForExit()

    $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
    $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_}) 
    Write-Log $output
    Write-Log $error Error

    $global:ExitCode = $packageTask.ExitCode
}

I see where the NuGet.exe command is created, so I modified it to:

$packageTask = Create-Process .\NuGet.exe ("pack -Properties Package.nuspec -Verbosity Detailed")

Then I get:

NuGet.CommandLineException: Please specify a nuspec or project file to use.

I removed the $configuration$\ segment of the file path, and then I got:

The replacement token 'id' has no value


Update: I replaced Package.nuspec with the name of the .csproj file for my project in NuGetPackage.ps1 and now building through Visual Studio properly creates the .nupkg file. I'd rather not do this for every NuGet package, though.


How can I use replacement tokens in Package.nuspec when building from Visual Studio rather than the command line?

1

1 Answers

0
votes

I found a workaround. The default power shell script that packages your project included with the NuGet Packager project template in Visual Studio packages the .nuspec file. Changing that to the .csproj file for my project fixed the issue, which I had to do in two places:

# Create symbols package if any .pdb files are located in the lib folder
If ((Get-ChildItem *.pdb -Path .\lib -Recurse).Count -gt 0) {
    $packageTask = Create-Process .\NuGet.exe ("pack YourProject.csproj -Symbol -Verbosity Detailed")

    // ...
}
Else {
    $packageTask = Create-Process .\NuGet.exe ("pack YourProject.csproj -Verbosity Detailed")

    // ...
}

It's not 100% ideal, because the NuGet Packager project doesn't work perfectly out of the box, but it's a simple change to make.

Notice the change in the PowerShell build script from pack Package.nuspec to pack YourProject.csproj where you replace YourProject.csproj with the .csproj file for your NuGet package project.