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.