6
votes

I want to create a nuget package that contains only what is specified in my nuspec file, but still get the version from my csproj. In order to use the token I have to pack like:

nuget pack MyProj.csproj

But when I do it like this it adds some dependencies and creates an unwanted folder in my nuget package. My nuspec file is:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>    
    <id>Test</id>
    <version>$version$</version>
    <title>Test</title>
    <authors>Test</authors>
    <owners>Test</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Test</description>
    <summary>Test</summary>
    <releaseNotes>Test</releaseNotes>
    <copyright>Test</copyright>  
  </metadata>
  <files>
    <file src="bin\Debug\*.dll" target="lib\net45" />
    <file src="bin\Debug\MyProj.Wpf.exe" target="lib\net45" />
    <file src="bin\Debug\MyProj.Wpf.exe.config" target="lib\net45" />
  </files>
</package>

When I run the pack command the file it adds extra is the MyProj.Wpf.exe in the target="lib\net452"

Can I force it not to add the dependencies and this extra file? Or to do only what is specified in nuspec?

1

1 Answers

-1
votes

It's been a while since I posted this question. Since then I used a solution that worked for me, so I'm going to post it here for anyone that needs it.

I created a .csproj that modifies the .nuspec file and sets it's version according to the assembly file of the .csproj. To reduce the manual work I created a .bat file that called this .exe with arguments and finished creating the installer. I used Squirrel.Windows for the installer creation.

I created a NuspectVersionSetter.csproj to set the nuspec version. There are many ways to implement this, here goes a simple one:

static void Main(string[] args)
{
    try
    {
        if (args.Length < 2)
        {
            throw new Exception("Args are not correct");
        }
        var assemblyFilePath = args[0];
        var nuspecFilePath = args[1];
        IsFileValid(assemblyFilePath, ".cs");
        IsFileValid(nuspecFilePath, ".nuspec");
        var version = GetAssemblyVersion(assemblyFilePath);
        if (string.IsNullOrEmpty(version))
        {
            throw new Exception("Unable to get version");
        }
        WriteNuspec(nuspecFilePath, version);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
    }
}

static void WriteNuspec(string path, string version)
{
    var lines = File.ReadAllLines(path);
    string versionLine = null;
    for(var i = 0; i < lines.Length; ++i)
    {
        var line = lines[i];
        if (line.Contains("<version>") && line.Contains("</version>"))
        {
            var init = line.IndexOf("<version>") + "<version>".Length;
            var end = line.IndexOf("</version>");
            line = line.Remove(init, end - init);
            lines[i] = line.Insert(init, version);
            break;
        }
    }
    File.WriteAllLines(path, lines);
}

static void IsFileValid(string file, string extension)
{
    if (!File.Exists(file))
    {
        throw new Exception("Invalid file path: " + file);
    }
    if (!file.EndsWith(extension))
    {
        throw new Exception("Invalid file extension: " + file);
    }
}

static string GetAssemblyVersion(string path)
{
    var lines = File.ReadAllLines(path);
    foreach(var line in lines)
    {
        if(line.Contains("AssemblyVersion") && !line.Contains(".*"))
        {
            var parts = line.Split('\"');
            if (parts.Length != 3)
            {
                break;
            }
            return parts[1];
        }
    }
    foreach (var line in lines)
    {
        if (line.Contains("AssemblyFileVersion") && !line.Contains(".*"))
        {
            var parts = line.Split('\"');
            if (parts.Length != 3)
            {
                break;
            }
            return parts[1];
        }
    }
    foreach (var line in lines)
    {
        if (line.Contains("AssemblyInformationalVersion") && !line.Contains(".*"))
        {
            var parts = line.Split('\"');
            if (parts.Length != 3)
            {
                break;
            }
            return parts[1];
        }
    }
    throw new Exception("Unable to get version");
}

As explained before the .bat file also wrapped the Squirrel.Windows installer creation.

Small observations about the .bat:

  • NuspecVersionSetter was the .exe created from the .csproj above
  • This example assumes your NuspecVersionSetter.exe is inside a folder in your .csproj, therefore some paths may need to be adjusted
  • The Squirrel.Windows version is old in this example, you many need to change it

The .bat file I used was the following:

NuspecVersionSetter ../Properties/AssemblyInfo.cs mynuspec.nuspec
nuget pack
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%G in ('dir *.nupkg /b /a-d /od') do (
    SET newest=%%G
)

"../../packages/squirrel.windows.1.2.1/tools/Squirrel" --releasify !newest! -g installing.gif

If there are any questions about this answer, ask them in the comments.