diff --git a/dotnet-deb/Program.cs b/dotnet-deb/Program.cs
index 9ba46c3..402bb22 100644
--- a/dotnet-deb/Program.cs
+++ b/dotnet-deb/Program.cs
@@ -6,7 +6,7 @@ namespace Dotnet.Packaging
{
static int Main(string[] args)
{
- PackagingRunner runner = new PackagingRunner("Debian/Ubuntu installer package", "CreateDeb");
+ PackagingRunner runner = new PackagingRunner("Debian/Ubuntu installer package", "CreateDeb", "deb");
return runner.Run(args);
}
}
diff --git a/dotnet-deb/dotnet-deb.csproj b/dotnet-deb/dotnet-deb.csproj
index 89448fd..d6c67d9 100644
--- a/dotnet-deb/dotnet-deb.csproj
+++ b/dotnet-deb/dotnet-deb.csproj
@@ -14,6 +14,9 @@ See https://github.com/qmfrederik/dotnet-packaging/ for more information on how
+
+
+
diff --git a/dotnet-rpm/PackagingRunner.cs b/dotnet-rpm/PackagingRunner.cs
index 7ec0b77..44570ab 100644
--- a/dotnet-rpm/PackagingRunner.cs
+++ b/dotnet-rpm/PackagingRunner.cs
@@ -1,7 +1,16 @@
using McMaster.Extensions.CommandLineUtils;
+using Microsoft.Build.Locator;
+using Newtonsoft.Json;
using System;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
+using System.Linq;
using System.Text;
+using ConsoleLogger = Microsoft.Build.Logging.ConsoleLogger;
+using IMSBuildLogger = Microsoft.Build.Framework.ILogger;
+using LoggerVerbosity = Microsoft.Build.Framework.LoggerVerbosity;
+using MSBuild = Microsoft.Build.Evaluation;
namespace Dotnet.Packaging
{
@@ -9,11 +18,15 @@ namespace Dotnet.Packaging
{
private readonly string outputName;
private readonly string msbuildTarget;
+ private readonly string commandName;
- public PackagingRunner(string outputName, string msbuildTarget)
+ public PackagingRunner(string outputName, string msbuildTarget, string commandName)
{
+ MSBuildLocator.RegisterDefaults();
+
this.outputName = outputName;
this.msbuildTarget = msbuildTarget;
+ this.commandName = commandName;
}
public int Run(string[] args)
@@ -36,40 +49,84 @@ namespace Dotnet.Packaging
CommandOptionType.SingleValue);
CommandOption versionSuffix = commandLineApplication.Option(
- "---version-suffix ",
+ "--version-suffix ",
"Defines the value for the $(VersionSuffix) property in the project.",
CommandOptionType.SingleValue);
+ CommandOption noRestore = commandLineApplication.Option(
+ "--no-restore",
+ "Do not restore the project before building.",
+ CommandOptionType.NoValue);
+
commandLineApplication.HelpOption("-? | -h | --help");
- commandLineApplication.FullName = $"dotnet {this.outputName}";
+ commandLineApplication.FullName = $"dotnet {this.commandName}";
commandLineApplication.LongVersionGetter = () => ThisAssembly.AssemblyInformationalVersion;
commandLineApplication.ExtendedHelpText = $"{Environment.NewLine}See https://github.com/qmfrederik/dotnet-packaging for more information";
+ var installCommand = commandLineApplication.Command(
+ "install",
+ command => command.OnExecute(() =>
+ {
+ Console.WriteLine($"dotnet {this.commandName} ({ThisAssembly.AssemblyInformationalVersion})");
+
+ // Create/update the Directory.Build.props file in the directory of the version.json file to add the Packaging.Targets package.
+ string directoryBuildPropsPath = Path.Combine(Environment.CurrentDirectory, "Directory.Build.props");
+ MSBuild.Project propsFile;
+ if (File.Exists(directoryBuildPropsPath))
+ {
+ propsFile = new MSBuild.Project(directoryBuildPropsPath);
+ }
+ else
+ {
+ propsFile = new MSBuild.Project();
+ }
+
+ const string PackageReferenceItemType = "PackageReference";
+ const string PackageId = "Packaging.Targets";
+ if (!propsFile.GetItemsByEvaluatedInclude(PackageId).Any(i => i.ItemType == PackageReferenceItemType && i.EvaluatedInclude == PackageId))
+ {
+ string packageVersion = ThisAssembly.AssemblyInformationalVersion.Replace("+", "-g");
+ propsFile.AddItem(
+ PackageReferenceItemType,
+ PackageId,
+ new Dictionary
+ {
+ { "Version", packageVersion },
+ { "PrivateAssets", "all" },
+ });
+
+ propsFile.Save(directoryBuildPropsPath);
+ }
+
+ Console.WriteLine($"Successfully installed dotnet {this.commandName}. Now run 'dotnet {this.commandName}' to package your");
+ Console.WriteLine($"application as a {this.outputName}");
+ }));
+
commandLineApplication.OnExecute(() =>
{
- Console.WriteLine($"dotnet {this.outputName} ({ThisAssembly.AssemblyInformationalVersion})");
+ Console.WriteLine($"dotnet {this.commandName} ({ThisAssembly.AssemblyInformationalVersion})");
- if (!framework.HasValue())
+ if (!noRestore.HasValue())
{
- Console.WriteLine("You must specify a target framework.");
- commandLineApplication.ShowHint();
-
- return -1;
- }
-
- if (!runtime.HasValue())
- {
- Console.WriteLine("You must specify a target runtime.");
- commandLineApplication.ShowHint();
-
- return -1;
+ if (!this.IsPackagingTargetsInstalled())
+ {
+ return -1;
+ }
}
StringBuilder msbuildArguments = new StringBuilder();
msbuildArguments.Append($"msbuild /t:{msbuildTarget} ");
- msbuildArguments.Append($"/p:RuntimeIdentifier={runtime.Value()} ");
- msbuildArguments.Append($"/p:TargetFramework={framework.Value()} ");
+
+ if (runtime.HasValue())
+ {
+ msbuildArguments.Append($"/p:RuntimeIdentifier={runtime.Value()} ");
+ }
+
+ if (framework.HasValue())
+ {
+ msbuildArguments.Append($"/p:TargetFramework={framework.Value()} ");
+ }
if (configuration.HasValue())
{
@@ -81,25 +138,77 @@ namespace Dotnet.Packaging
msbuildArguments.Append($"/p:VersionSuffix={versionSuffix.Value()} ");
}
- var psi = new ProcessStartInfo
- {
- FileName = "dotnet",
- Arguments = msbuildArguments.ToString()
- };
-
- var process = new Process
- {
- StartInfo = psi,
-
- };
-
- process.Start();
- process.WaitForExit();
-
- return process.ExitCode;
+ return RunDotnet(msbuildArguments);
});
return commandLineApplication.Execute(args);
}
+
+ public int RunDotnet(StringBuilder msbuildArguments)
+ {
+ var psi = new ProcessStartInfo
+ {
+ FileName = "dotnet",
+ Arguments = msbuildArguments.ToString()
+ };
+
+ var process = new Process
+ {
+ StartInfo = psi,
+
+ };
+
+ process.Start();
+ process.WaitForExit();
+
+ return process.ExitCode;
+ }
+
+ public bool IsPackagingTargetsInstalled()
+ {
+ var projectFilePath = Directory.GetFiles(Environment.CurrentDirectory, "*.csproj").SingleOrDefault();
+
+ if (projectFilePath == null)
+ {
+ Console.Error.WriteLine($"Failed to find a .csproj file in '{Environment.CurrentDirectory}'. dotnet {this.commandName} only works if");
+ Console.Error.WriteLine($"you have exactly one .csproj file in your directory. For advanced scenarios, please use 'dotnet msbuild /t:{this.msbuildTarget}'");
+ return false;
+ }
+
+ var loggers = new IMSBuildLogger[] { new ConsoleLogger(LoggerVerbosity.Quiet) };
+ var project = new MSBuild.Project(projectFilePath);
+
+ if (!project.Build("Restore", loggers))
+ {
+ Console.Error.WriteLine($"Failed to restore '{Path.GetFileName(projectFilePath)}'. Please run dotnet restore, and try again.");
+ return false;
+ }
+
+ var projectAssetsPath = project.GetPropertyValue("ProjectAssetsFile");
+
+ // NuGet has a LockFileUtilities.GetLockFile API which provides direct access to this file format,
+ // but loading NuGet in the same process as MSBuild creates dependency conflicts.
+ LockFile lockFile = null;
+ using (StreamReader reader = File.OpenText(projectAssetsPath))
+ using (JsonReader jsonReader = new JsonTextReader(reader))
+ {
+ JsonSerializer serializer = new JsonSerializer();
+ lockFile = serializer.Deserialize(jsonReader);
+ }
+
+ if (!lockFile.Libraries.Any(l => l.Key.StartsWith("Packaging.Targets/")))
+ {
+ Console.Error.WriteLine($"The project '{Path.GetFileName(projectFilePath)}' doesn't have a PackageReference to Packaging.Targets.");
+ Console.Error.WriteLine($"Please run 'dotnet {this.commandName} install', and try again.");
+ return false;
+ }
+
+ return true;
+ }
+
+ class LockFile
+ {
+ public Dictionary Libraries;
+ }
}
}
diff --git a/dotnet-rpm/Program.cs b/dotnet-rpm/Program.cs
index e0bb756..bc0a946 100644
--- a/dotnet-rpm/Program.cs
+++ b/dotnet-rpm/Program.cs
@@ -1,15 +1,10 @@
-using McMaster.Extensions.CommandLineUtils;
-using System;
-using System.Diagnostics;
-using System.Text;
-
-namespace Dotnet.Packaging
+namespace Dotnet.Packaging
{
public class Program
{
public static int Main(string[] args)
{
- PackagingRunner runner = new PackagingRunner("RPM package", "CreateRpm");
+ PackagingRunner runner = new PackagingRunner("RPM package", "CreateRpm", "rpm");
return runner.Run(args);
}
}
diff --git a/dotnet-rpm/dotnet-rpm.csproj b/dotnet-rpm/dotnet-rpm.csproj
index 45ecc1c..9b65e95 100644
--- a/dotnet-rpm/dotnet-rpm.csproj
+++ b/dotnet-rpm/dotnet-rpm.csproj
@@ -14,5 +14,8 @@ See https://github.com/qmfrederik/dotnet-packaging/ for more information on how
+
+
+
\ No newline at end of file
diff --git a/dotnet-tarball/Program.cs b/dotnet-tarball/Program.cs
index c3bf44d..1ace0ce 100644
--- a/dotnet-tarball/Program.cs
+++ b/dotnet-tarball/Program.cs
@@ -1,12 +1,10 @@
-using System.Diagnostics;
-
namespace Dotnet.Packaging
{
class Program
{
static int Main(string[] args)
{
- PackagingRunner runner = new PackagingRunner("tarball", "CreateTarball");
+ PackagingRunner runner = new PackagingRunner("tarball", "CreateTarball", "tarball");
return runner.Run(args);
}
}
diff --git a/dotnet-tarball/dotnet-tarball.csproj b/dotnet-tarball/dotnet-tarball.csproj
index 99a52a7..c64712b 100644
--- a/dotnet-tarball/dotnet-tarball.csproj
+++ b/dotnet-tarball/dotnet-tarball.csproj
@@ -14,6 +14,9 @@ See https://github.com/qmfrederik/dotnet-packaging/ for more information on how
+
+
+
diff --git a/dotnet-zip/Program.cs b/dotnet-zip/Program.cs
index 7ff0594..0e8403e 100644
--- a/dotnet-zip/Program.cs
+++ b/dotnet-zip/Program.cs
@@ -1,12 +1,10 @@
-using System.Diagnostics;
-
namespace Dotnet.Packaging
{
class Program
{
static int Main(string[] args)
{
- PackagingRunner runner = new PackagingRunner("zip archive", "CreateZip");
+ PackagingRunner runner = new PackagingRunner("zip archive", "CreateZip", "zip");
return runner.Run(args);
}
}
diff --git a/dotnet-zip/dotnet-zip.csproj b/dotnet-zip/dotnet-zip.csproj
index 05f1874..5175f41 100644
--- a/dotnet-zip/dotnet-zip.csproj
+++ b/dotnet-zip/dotnet-zip.csproj
@@ -14,6 +14,9 @@ See https://github.com/qmfrederik/dotnet-packaging/ for more information on how
+
+
+