mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Csq is compiling
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using NuGet.Common;
|
||||||
using NuGet.Versioning;
|
using NuGet.Versioning;
|
||||||
|
using Squirrel.NuGet;
|
||||||
|
|
||||||
namespace Squirrel.Csq.Commands;
|
namespace Squirrel.Csq.Commands;
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ internal static class SystemCommandLineExtensions
|
|||||||
|
|
||||||
public static CliOption<T> SetDefault<T>(this CliOption<T> option, T defaultValue)
|
public static CliOption<T> SetDefault<T>(this CliOption<T> option, T defaultValue)
|
||||||
{
|
{
|
||||||
option.SetDefault(defaultValue);
|
option.DefaultValueFactory = (r) => defaultValue;
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,10 +275,9 @@ internal static class SystemCommandLineExtensions
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < result.Tokens.Count; i++) {
|
for (var i = 0; i < result.Tokens.Count; i++) {
|
||||||
var framework = result.Tokens[i].Value;
|
var framework = result.Tokens[i].Value;
|
||||||
try {
|
bool valid = framework.Split(",").Select(Runtimes.GetRuntimeByName).All(x => x != null);
|
||||||
Runtimes.ParseDependencyString(framework);
|
if (!valid) {
|
||||||
} catch (Exception e) {
|
result.AddError($"Invalid target dependency string: {framework}.");
|
||||||
result.AddError(e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
using Squirrel.Packaging;
|
||||||
|
|
||||||
namespace Squirrel.Csq.Commands;
|
namespace Squirrel.Csq.Commands;
|
||||||
|
|
||||||
public class SigningCommand : BaseCommand
|
public class SigningCommand : BaseCommand
|
||||||
|
|||||||
112
src/Squirrel.Csq/Compat/EmbeddedRunner.cs
Normal file
112
src/Squirrel.Csq/Compat/EmbeddedRunner.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using System.Runtime.Versioning;
|
||||||
|
using Squirrel.Csq.Commands;
|
||||||
|
using Squirrel.Deployment;
|
||||||
|
using Squirrel.Packaging.OSX;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public class EmbeddedRunner : ICommandRunner
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public EmbeddedRunner(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SupportedOSPlatform("osx")]
|
||||||
|
public Task ExecuteBundleOsx(BundleOsxCommand command)
|
||||||
|
{
|
||||||
|
var options = new BundleOsxOptions {
|
||||||
|
BundleId = command.BundleId,
|
||||||
|
PackAuthors = command.PackAuthors,
|
||||||
|
EntryExecutableName = command.EntryExecutableName,
|
||||||
|
Icon = command.Icon,
|
||||||
|
PackDirectory = command.PackDirectory,
|
||||||
|
PackId = command.PackId,
|
||||||
|
PackTitle = command.PackTitle,
|
||||||
|
PackVersion = command.PackVersion,
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
};
|
||||||
|
new OsxCommands(_logger).Bundle(options);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteGithubDownload(GitHubDownloadCommand command)
|
||||||
|
{
|
||||||
|
var options = new GitHubDownloadOptions {
|
||||||
|
Pre = command.Pre,
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
RepoUrl = command.RepoUrl,
|
||||||
|
Token = command.Token,
|
||||||
|
};
|
||||||
|
return new GitHubRepository(_logger).DownloadRecentPackages(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteGithubUpload(GitHubUploadCommand command)
|
||||||
|
{
|
||||||
|
var options = new GitHubUploadOptions {
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
RepoUrl = command.RepoUrl,
|
||||||
|
Token = command.Token,
|
||||||
|
Publish = command.Publish,
|
||||||
|
ReleaseName = command.ReleaseName,
|
||||||
|
};
|
||||||
|
return new GitHubRepository(_logger).UploadMissingPackages(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteHttpDownload(HttpDownloadCommand command)
|
||||||
|
{
|
||||||
|
var options = new HttpDownloadOptions {
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
Url = command.Url,
|
||||||
|
};
|
||||||
|
return new SimpleWebRepository(_logger).DownloadRecentPackages(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecutePackWindows(PackWindowsCommand command)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
[SupportedOSPlatform("osx")]
|
||||||
|
public Task ExecuteReleasifyOsx(ReleasifyOsxCommand command)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteReleasifyWindows(ReleasifyWindowsCommand command)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteS3Download(S3DownloadCommand command)
|
||||||
|
{
|
||||||
|
var options = new S3Options {
|
||||||
|
Bucket = command.Bucket,
|
||||||
|
Endpoint = command.Endpoint,
|
||||||
|
KeyId = command.KeyId,
|
||||||
|
PathPrefix = command.PathPrefix,
|
||||||
|
Region = command.Region,
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
Secret = command.Secret,
|
||||||
|
};
|
||||||
|
return new S3Repository(_logger).DownloadRecentPackages(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteS3Upload(S3UploadCommand command)
|
||||||
|
{
|
||||||
|
var options = new S3UploadOptions {
|
||||||
|
Bucket = command.Bucket,
|
||||||
|
Endpoint = command.Endpoint,
|
||||||
|
KeyId = command.KeyId,
|
||||||
|
PathPrefix = command.PathPrefix,
|
||||||
|
Region = command.Region,
|
||||||
|
ReleaseDir = command.GetReleaseDirectory(),
|
||||||
|
Secret = command.Secret,
|
||||||
|
KeepMaxReleases = command.KeepMaxReleases,
|
||||||
|
Overwrite = command.Overwrite,
|
||||||
|
};
|
||||||
|
return new S3Repository(_logger).UploadMissingPackages(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Squirrel.Csq/Compat/ICommandRunner.cs
Normal file
17
src/Squirrel.Csq/Compat/ICommandRunner.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Runtime.Versioning;
|
||||||
|
using Squirrel.Csq.Commands;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public interface ICommandRunner
|
||||||
|
{
|
||||||
|
public Task ExecuteGithubDownload(GitHubDownloadCommand command);
|
||||||
|
public Task ExecuteGithubUpload(GitHubUploadCommand command);
|
||||||
|
public Task ExecuteHttpDownload(HttpDownloadCommand command);
|
||||||
|
public Task ExecuteS3Download(S3DownloadCommand command);
|
||||||
|
public Task ExecuteS3Upload(S3UploadCommand command);
|
||||||
|
public Task ExecuteBundleOsx(BundleOsxCommand command);
|
||||||
|
public Task ExecuteReleasifyOsx(ReleasifyOsxCommand command);
|
||||||
|
public Task ExecuteReleasifyWindows(ReleasifyWindowsCommand command);
|
||||||
|
public Task ExecutePackWindows(PackWindowsCommand command);
|
||||||
|
}
|
||||||
9
src/Squirrel.Csq/Compat/IRunnerFactory.cs
Normal file
9
src/Squirrel.Csq/Compat/IRunnerFactory.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Squirrel.Csq.Commands;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public interface IRunnerFactory
|
||||||
|
{
|
||||||
|
public Task CreateAndExecuteAsync<T>(string commandName, T options) where T : BaseCommand;
|
||||||
|
public Task<ICommandRunner> CreateAsync();
|
||||||
|
}
|
||||||
105
src/Squirrel.Csq/Compat/RunnerFactory.cs
Normal file
105
src/Squirrel.Csq/Compat/RunnerFactory.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Squirrel.Csq.Commands;
|
||||||
|
using Squirrel.Csq.Updates;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public class RunnerFactory : IRunnerFactory
|
||||||
|
{
|
||||||
|
private const string CLOWD_PACKAGE_NAME = "Clowd.Squirrel";
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly FileSystemInfo _solution;
|
||||||
|
private readonly IConfiguration _config;
|
||||||
|
|
||||||
|
public RunnerFactory(ILogger logger, FileSystemInfo solution, IConfiguration config)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_solution = solution;
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CreateAndExecuteAsync<T>(string commandName, T options) where T : BaseCommand
|
||||||
|
{
|
||||||
|
var runner = await CreateAsync();
|
||||||
|
var method = typeof(ICommandRunner).GetMethod(commandName);
|
||||||
|
await (Task) method.Invoke(runner, new object[] { options });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICommandRunner> CreateAsync()
|
||||||
|
{
|
||||||
|
if (_config.GetValue<bool?>("SKIP_UPDATE_CHECK") != true) {
|
||||||
|
var updateCheck = new UpdateChecker(_logger);
|
||||||
|
await updateCheck.CheckForUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
var solutionDir = FindSolutionDirectory(_solution?.FullName);
|
||||||
|
|
||||||
|
if (solutionDir is null) {
|
||||||
|
throw new Exception($"Could not find '.sln'. Specify solution or solution directory with '--solution='.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var version = new SquirrelVersionLocator(_logger).Search(solutionDir, CLOWD_PACKAGE_NAME);
|
||||||
|
|
||||||
|
if (version.Major == 4) {
|
||||||
|
var myVer = SquirrelRuntimeInfo.SquirrelNugetVersion;
|
||||||
|
if (version != myVer) {
|
||||||
|
_logger.Warn($"Installed SDK is {version}, while csq is {myVer}, this is not recommended.");
|
||||||
|
}
|
||||||
|
return new EmbeddedRunner(_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.Major == 2 && version.Minor > 7) {
|
||||||
|
_logger.Warn("Running in V2 compatibility mode. Not all features may be available.");
|
||||||
|
|
||||||
|
Dictionary<string, string> packageSearchPaths = new();
|
||||||
|
var nugetPackagesDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||||
|
packageSearchPaths.Add("nuget user profile cache", Path.Combine(nugetPackagesDir, CLOWD_PACKAGE_NAME.ToLower(), "{0}", "tools"));
|
||||||
|
packageSearchPaths.Add("visual studio packages cache", Path.Combine(solutionDir, "packages", CLOWD_PACKAGE_NAME + ".{0}", "tools"));
|
||||||
|
string squirrelExe = null;
|
||||||
|
|
||||||
|
foreach (var kvp in packageSearchPaths) {
|
||||||
|
var path = String.Format(kvp.Value, version);
|
||||||
|
if (Directory.Exists(path)) {
|
||||||
|
_logger.Debug($"Found {CLOWD_PACKAGE_NAME} {version} from {kvp.Key}");
|
||||||
|
var toolExePath = Path.Combine(path, "Squirrel.exe");
|
||||||
|
if (File.Exists(toolExePath)) {
|
||||||
|
squirrelExe = toolExePath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squirrelExe is null) {
|
||||||
|
throw new Exception($"Could not find {CLOWD_PACKAGE_NAME} {version} Squirrel.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new V2CompatRunner(_logger, squirrelExe);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotSupportedException($"Squirrel {version} is installed in this project, but not supported by this version of Csq. Supported versions are [> v2.8] and [> v4.0]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FindSolutionDirectory(string slnArgument)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrWhiteSpace(slnArgument)) {
|
||||||
|
if (File.Exists(slnArgument) && slnArgument.EndsWith(".sln", StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
|
// we were given a sln file as argument
|
||||||
|
return Path.GetDirectoryName(Path.GetFullPath(slnArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.Exists(slnArgument) && Directory.EnumerateFiles(slnArgument, "*.sln").Any()) {
|
||||||
|
return Path.GetFullPath(slnArgument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find the solution directory from cwd
|
||||||
|
var cwd = Environment.CurrentDirectory;
|
||||||
|
var slnSearchDirs = new string[] {
|
||||||
|
cwd,
|
||||||
|
Path.Combine(cwd, ".."),
|
||||||
|
Path.Combine(cwd, "..", ".."),
|
||||||
|
};
|
||||||
|
|
||||||
|
return slnSearchDirs.FirstOrDefault(d => Directory.EnumerateFiles(d, "*.sln").Any());
|
||||||
|
}
|
||||||
|
}
|
||||||
85
src/Squirrel.Csq/Compat/SquirrelVersionLocator.cs
Normal file
85
src/Squirrel.Csq/Compat/SquirrelVersionLocator.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.Build.Construction;
|
||||||
|
using NuGet.Versioning;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public class SquirrelVersionLocator
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public SquirrelVersionLocator(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NuGetVersion Search(string solutionDir, string packageName)
|
||||||
|
{
|
||||||
|
var dependencies = GetPackageVersionsFromDir(solutionDir, packageName).Distinct().ToArray();
|
||||||
|
|
||||||
|
if (dependencies.Length == 0) {
|
||||||
|
throw new Exception($"{packageName} nuget package was not found installed in solution.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependencies.Length > 1) {
|
||||||
|
throw new Exception($"Found multiple versions of {packageName} installed in solution ({string.Join(", ", dependencies)}). " +
|
||||||
|
$"Please consolidate to a single version.'");
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetVersion = dependencies.Single();
|
||||||
|
return NuGetVersion.Parse(targetVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<string> GetPackageVersionsFromDir(string rootDir, string packageName)
|
||||||
|
{
|
||||||
|
// old-style framework packages.config
|
||||||
|
foreach (var packagesFile in EnumerateFilesUntilSpecificDepth(rootDir, "packages.config", 3)) {
|
||||||
|
using var xmlStream = File.OpenRead(packagesFile);
|
||||||
|
var xdoc = XDocument.Load(xmlStream);
|
||||||
|
|
||||||
|
var sqel = xdoc.Root?.Elements().FirstOrDefault(e => e.Attribute("id")?.Value == packageName);
|
||||||
|
var ver = sqel?.Attribute("version");
|
||||||
|
if (ver == null) continue;
|
||||||
|
|
||||||
|
_logger.Debug($"{packageName} {ver.Value} referenced in {packagesFile}");
|
||||||
|
|
||||||
|
if (ver.Value.Contains('*'))
|
||||||
|
throw new Exception(
|
||||||
|
$"Wildcard versions are not supported in packages.config. Remove wildcard or upgrade csproj format to use PackageReference.");
|
||||||
|
|
||||||
|
yield return ver.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new-style csproj PackageReference
|
||||||
|
foreach (var projFile in EnumerateFilesUntilSpecificDepth(rootDir, "*.csproj", 3)) {
|
||||||
|
var proj = ProjectRootElement.Open(projFile);
|
||||||
|
if (proj == null) continue;
|
||||||
|
|
||||||
|
ProjectItemElement item = proj.Items.FirstOrDefault(i => i.ItemType == "PackageReference" && i.Include == packageName);
|
||||||
|
if (item == null) continue;
|
||||||
|
|
||||||
|
var version = item.Children.FirstOrDefault(x => x.ElementName == "Version") as ProjectMetadataElement;
|
||||||
|
if (version?.Value == null) continue;
|
||||||
|
|
||||||
|
_logger.Debug($"{packageName} {version.Value} referenced in {projFile}");
|
||||||
|
|
||||||
|
yield return version.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<string> EnumerateFilesUntilSpecificDepth(string rootPath, string searchPattern, int maxDepth, int currentDepth = 0)
|
||||||
|
{
|
||||||
|
var files = Directory.EnumerateFiles(rootPath, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (var f in files) {
|
||||||
|
yield return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDepth < maxDepth) {
|
||||||
|
foreach (var dir in Directory.EnumerateDirectories(rootPath)) {
|
||||||
|
foreach (var file in EnumerateFilesUntilSpecificDepth(dir, searchPattern, maxDepth, currentDepth + 1)) {
|
||||||
|
yield return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
275
src/Squirrel.Csq/Compat/V2CompatRunner.cs
Normal file
275
src/Squirrel.Csq/Compat/V2CompatRunner.cs
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using Squirrel.Csq.Commands;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Compat;
|
||||||
|
|
||||||
|
public class V2CompatRunner : ICommandRunner
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly string _squirrelExePath;
|
||||||
|
private readonly EmbeddedRunner _embedded;
|
||||||
|
|
||||||
|
public V2CompatRunner(ILogger logger, string squirrelExePath)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_squirrelExePath = squirrelExePath;
|
||||||
|
_embedded = new EmbeddedRunner(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecutePackWindows(PackWindowsCommand command)
|
||||||
|
{
|
||||||
|
if (!SquirrelRuntimeInfo.IsWindows || command.TargetRuntime.BaseRID != RuntimeOs.Windows) {
|
||||||
|
throw new NotSupportedException("Squirrel v2.x is only supported on/for Windows.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string msi = null;
|
||||||
|
if (command.BuildMsi) {
|
||||||
|
msi = command.TargetRuntime.Architecture.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new PackOptions {
|
||||||
|
releaseDir = command.GetReleaseDirectory().FullName,
|
||||||
|
package = command.Package,
|
||||||
|
baseUrl = command.BaseUrl,
|
||||||
|
framework = command.Runtimes,
|
||||||
|
splashImage = command.SplashImage,
|
||||||
|
icon = command.Icon,
|
||||||
|
appIcon = command.AppIcon,
|
||||||
|
noDelta = command.NoDelta,
|
||||||
|
allowUnaware = false,
|
||||||
|
msi = msi,
|
||||||
|
signParams = command.SignParameters,
|
||||||
|
signTemplate = command.SignTemplate,
|
||||||
|
packId = command.PackId,
|
||||||
|
includePdb = command.IncludePdb,
|
||||||
|
packAuthors = command.PackAuthors,
|
||||||
|
packDirectory = command.PackDirectory,
|
||||||
|
packTitle = command.PackTitle,
|
||||||
|
packVersion = command.PackVersion,
|
||||||
|
releaseNotes = command.ReleaseNotes,
|
||||||
|
};
|
||||||
|
|
||||||
|
var args = new List<string> { "pack" };
|
||||||
|
options.AddArgs(args);
|
||||||
|
_logger.Debug($"Running V2 Squirrel.exe: '{_squirrelExePath} {String.Join(" ", args)}'");
|
||||||
|
await Process.Start(_squirrelExePath, args).WaitForExitAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteReleasifyWindows(ReleasifyWindowsCommand command)
|
||||||
|
{
|
||||||
|
if (!SquirrelRuntimeInfo.IsWindows || command.TargetRuntime.BaseRID != RuntimeOs.Windows) {
|
||||||
|
throw new NotSupportedException("Squirrel v2.x is only supported on/for Windows.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string msi = null;
|
||||||
|
if (command.BuildMsi) {
|
||||||
|
msi = command.TargetRuntime.Architecture.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new ReleasifyOptions {
|
||||||
|
releaseDir = command.GetReleaseDirectory().FullName,
|
||||||
|
package = command.Package,
|
||||||
|
baseUrl = command.BaseUrl,
|
||||||
|
framework = command.Runtimes,
|
||||||
|
splashImage = command.SplashImage,
|
||||||
|
icon = command.Icon,
|
||||||
|
appIcon = command.AppIcon,
|
||||||
|
noDelta = command.NoDelta,
|
||||||
|
allowUnaware = false,
|
||||||
|
msi = msi,
|
||||||
|
signParams = command.SignParameters,
|
||||||
|
signTemplate = command.SignTemplate,
|
||||||
|
};
|
||||||
|
|
||||||
|
var args = new List<string> { "releasify" };
|
||||||
|
options.AddArgs(args);
|
||||||
|
_logger.Debug($"Running V2 Squirrel.exe: '{_squirrelExePath} {String.Join(" ", args)}'");
|
||||||
|
await Process.Start(_squirrelExePath, args).WaitForExitAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteBundleOsx(BundleOsxCommand command)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Squirrel v2.x is only supported on/for Windows.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteReleasifyOsx(ReleasifyOsxCommand command)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Squirrel v2.x is only supported on/for Windows.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteGithubDownload(GitHubDownloadCommand command)
|
||||||
|
{
|
||||||
|
return ((ICommandRunner) _embedded).ExecuteGithubDownload(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteGithubUpload(GitHubUploadCommand command)
|
||||||
|
{
|
||||||
|
return ((ICommandRunner) _embedded).ExecuteGithubUpload(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteHttpDownload(HttpDownloadCommand command)
|
||||||
|
{
|
||||||
|
return ((ICommandRunner) _embedded).ExecuteHttpDownload(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteS3Download(S3DownloadCommand command)
|
||||||
|
{
|
||||||
|
return ((ICommandRunner) _embedded).ExecuteS3Download(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteS3Upload(S3UploadCommand command)
|
||||||
|
{
|
||||||
|
return ((ICommandRunner) _embedded).ExecuteS3Upload(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class BaseOptions
|
||||||
|
{
|
||||||
|
public string releaseDir { get; set; }
|
||||||
|
|
||||||
|
public virtual void AddArgs(List<string> args)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrWhiteSpace(releaseDir)) {
|
||||||
|
args.Add("--releaseDir");
|
||||||
|
args.Add(releaseDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SigningOptions : BaseOptions
|
||||||
|
{
|
||||||
|
public string signParams { get; set; }
|
||||||
|
public string signTemplate { get; set; }
|
||||||
|
|
||||||
|
public override void AddArgs(List<string> args)
|
||||||
|
{
|
||||||
|
base.AddArgs(args);
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(signParams)) {
|
||||||
|
args.Add("--signParams");
|
||||||
|
args.Add(signParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(signTemplate)) {
|
||||||
|
args.Add("--signTemplate");
|
||||||
|
args.Add(signTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ReleasifyOptions : SigningOptions
|
||||||
|
{
|
||||||
|
public string package { get; set; }
|
||||||
|
public string baseUrl { get; set; }
|
||||||
|
public string framework { get; set; }
|
||||||
|
public string splashImage { get; set; }
|
||||||
|
public string icon { get; set; }
|
||||||
|
public string appIcon { get; set; }
|
||||||
|
public bool noDelta { get; set; }
|
||||||
|
public bool allowUnaware { get; set; }
|
||||||
|
public string msi { get; set; }
|
||||||
|
public string debugSetupExe { get; set; }
|
||||||
|
|
||||||
|
public override void AddArgs(List<string> args)
|
||||||
|
{
|
||||||
|
base.AddArgs(args);
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(package)) {
|
||||||
|
args.Add("--package");
|
||||||
|
args.Add(package);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(baseUrl)) {
|
||||||
|
args.Add("--baseUrl");
|
||||||
|
args.Add(baseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(framework)) {
|
||||||
|
args.Add("--framework");
|
||||||
|
args.Add(framework);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(splashImage)) {
|
||||||
|
args.Add("--splashImage");
|
||||||
|
args.Add(splashImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(icon)) {
|
||||||
|
args.Add("--icon");
|
||||||
|
args.Add(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(appIcon)) {
|
||||||
|
args.Add("--appIcon");
|
||||||
|
args.Add(appIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noDelta) {
|
||||||
|
args.Add("--noDelta");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowUnaware) {
|
||||||
|
args.Add("--allowUnaware");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(msi)) {
|
||||||
|
args.Add("--msi");
|
||||||
|
args.Add(msi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(debugSetupExe)) {
|
||||||
|
args.Add("--debugSetupExe");
|
||||||
|
args.Add(debugSetupExe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PackOptions : ReleasifyOptions
|
||||||
|
{
|
||||||
|
public string packId { get; set; }
|
||||||
|
public string packTitle { get; set; }
|
||||||
|
public string packVersion { get; set; }
|
||||||
|
public string packAuthors { get; set; }
|
||||||
|
public string packDirectory { get; set; }
|
||||||
|
public bool includePdb { get; set; }
|
||||||
|
public string releaseNotes { get; set; }
|
||||||
|
|
||||||
|
public override void AddArgs(List<string> args)
|
||||||
|
{
|
||||||
|
base.AddArgs(args);
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(packId)) {
|
||||||
|
args.Add("--packId");
|
||||||
|
args.Add(packId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(packTitle)) {
|
||||||
|
args.Add("--packTitle");
|
||||||
|
args.Add(packTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(packVersion)) {
|
||||||
|
args.Add("--packVersion");
|
||||||
|
args.Add(packVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(packAuthors)) {
|
||||||
|
args.Add("--packAuthors");
|
||||||
|
args.Add(packAuthors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(packDirectory)) {
|
||||||
|
args.Add("--packDir");
|
||||||
|
args.Add(packDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includePdb) {
|
||||||
|
args.Add("--includePdb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(releaseNotes)) {
|
||||||
|
args.Add("--releaseNotes");
|
||||||
|
args.Add(releaseNotes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using NuGet.Common;
|
|
||||||
using NuGet.Configuration;
|
|
||||||
using NuGet.Packaging.Core;
|
|
||||||
using NuGet.Protocol.Core.Types;
|
|
||||||
using NuGet.Versioning;
|
|
||||||
|
|
||||||
namespace Squirrel.Tool
|
|
||||||
{
|
|
||||||
public class NugetDownloader
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly PackageSource _packageSource;
|
|
||||||
private readonly SourceRepository _sourceRepository;
|
|
||||||
private readonly SourceCacheContext _sourceCacheContext;
|
|
||||||
|
|
||||||
public NugetDownloader(ILogger logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_packageSource = new PackageSource("https://api.nuget.org/v3/index.json", "NuGet.org");
|
|
||||||
_sourceRepository = new SourceRepository(_packageSource, Repository.Provider.GetCoreV3());
|
|
||||||
_sourceCacheContext = new SourceCacheContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IPackageSearchMetadata> GetPackageMetadata(string packageName, string version, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
PackageMetadataResource packageMetadataResource = _sourceRepository.GetResource<PackageMetadataResource>();
|
|
||||||
FindPackageByIdResource packageByIdResource = _sourceRepository.GetResource<FindPackageByIdResource>();
|
|
||||||
IPackageSearchMetadata package = null;
|
|
||||||
|
|
||||||
var prerelease = version?.Equals("pre", StringComparison.InvariantCultureIgnoreCase) == true;
|
|
||||||
if (version is null || version.Equals("latest", StringComparison.InvariantCultureIgnoreCase) || prerelease) {
|
|
||||||
// get latest (or prerelease) version
|
|
||||||
IEnumerable<IPackageSearchMetadata> metadata = await packageMetadataResource
|
|
||||||
.GetMetadataAsync(packageName, true, true, _sourceCacheContext, _logger, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
package = metadata
|
|
||||||
.Where(x => x.IsListed)
|
|
||||||
.Where(x => prerelease || !x.Identity.Version.IsPrerelease)
|
|
||||||
.OrderByDescending(x => x.Identity.Version)
|
|
||||||
.FirstOrDefault();
|
|
||||||
} else {
|
|
||||||
// resolve version ranges and wildcards
|
|
||||||
var versions = await packageByIdResource.GetAllVersionsAsync(packageName, _sourceCacheContext, _logger, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
var resolved = versions.FindBestMatch(VersionRange.Parse(version), version => version);
|
|
||||||
|
|
||||||
// get exact version
|
|
||||||
var packageIdentity = new PackageIdentity(packageName, resolved);
|
|
||||||
package = await packageMetadataResource
|
|
||||||
.GetMetadataAsync(packageIdentity, _sourceCacheContext, _logger, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (package is null) {
|
|
||||||
throw new Exception($"Unable to locate {packageName} {version} on NuGet.org");
|
|
||||||
}
|
|
||||||
|
|
||||||
return package;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DownloadPackageToStream(IPackageSearchMetadata package, Stream targetStream, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
FindPackageByIdResource packageByIdResource = _sourceRepository.GetResource<FindPackageByIdResource>();
|
|
||||||
await packageByIdResource
|
|
||||||
.CopyNupkgToStreamAsync(package.Identity.Id, package.Identity.Version, targetStream, _sourceCacheContext, _logger, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using NugetLevel = NuGet.Common.LogLevel;
|
|
||||||
using NugetLogger = NuGet.Common.ILogger;
|
|
||||||
using NugetMessage = NuGet.Common.ILogMessage;
|
|
||||||
|
|
||||||
namespace Squirrel.CommandLine
|
|
||||||
{
|
|
||||||
class NullNugetLogger : NugetLogger
|
|
||||||
{
|
|
||||||
void NugetLogger.LogDebug(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogVerbose(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogInformation(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogMinimal(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogWarning(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogError(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.LogInformationSummary(string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.Log(NugetLevel level, string data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Task NugetLogger.LogAsync(NugetLevel level, string data)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NugetLogger.Log(NugetMessage message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Task NugetLogger.LogAsync(NugetMessage message)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
//using System;
|
|
||||||
//using System.Collections.Generic;
|
|
||||||
//using System.CommandLine;
|
|
||||||
//using System.CommandLine.Builder;
|
|
||||||
//using System.CommandLine.Invocation;
|
|
||||||
//using System.CommandLine.Parsing;
|
|
||||||
//using System.Diagnostics;
|
|
||||||
//using System.IO;
|
|
||||||
//using System.Linq;
|
|
||||||
//using System.Threading;
|
|
||||||
//using System.Threading.Tasks;
|
|
||||||
//using System.Xml;
|
|
||||||
//using System.Xml.Linq;
|
|
||||||
//using Microsoft.Build.Construction;
|
|
||||||
//using Microsoft.Extensions.Configuration;
|
|
||||||
//using Microsoft.Extensions.Hosting;
|
|
||||||
//using Squirrel.CommandLine;
|
|
||||||
|
|
||||||
//namespace Squirrel.Tool
|
|
||||||
//{
|
|
||||||
// class Program
|
|
||||||
// {
|
|
||||||
// const string CLOWD_PACKAGE_NAME = "Clowd.Squirrel";
|
|
||||||
|
|
||||||
// private static ConsoleLogger _logger;
|
|
||||||
|
|
||||||
// private static CliOption<string> CsqVersion { get; }
|
|
||||||
// = new CliOption<string>("--csq-version");
|
|
||||||
// private static CliOption<FileSystemInfo> CsqSolutionPath { get; }
|
|
||||||
// = new CliOption<FileSystemInfo>(new[] { "--csq-sln", "--csq-solution" }).ExistingOnly();
|
|
||||||
// private static CliOption<bool> Verbose { get; }
|
|
||||||
// = new CliOption<bool>("--verbose");
|
|
||||||
|
|
||||||
// static Task<int> Main(string[] args)
|
|
||||||
// {
|
|
||||||
|
|
||||||
// HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
|
|
||||||
// builder.Environment.ContentRootPath = Directory.GetCurrentDirectory();
|
|
||||||
// builder.Configuration.AddJsonFile("hostsettings.json", optional: true);
|
|
||||||
// builder.Configuration.AddEnvironmentVariables(prefix: "PREFIX_");
|
|
||||||
// builder.Configuration.AddCommandLine(args);
|
|
||||||
// _logger = ConsoleLogger.RegisterLogger();
|
|
||||||
|
|
||||||
// System.CommandLine.Hosting.HostingExtensions.
|
|
||||||
|
|
||||||
// CliRootCommand rootCommand = new CliRootCommand() {
|
|
||||||
// CsqVersion,
|
|
||||||
// CsqSolutionPath,
|
|
||||||
// Verbose
|
|
||||||
// };
|
|
||||||
// rootCommand.TreatUnmatchedTokensAsErrors = false;
|
|
||||||
|
|
||||||
// rootCommand.SetHandler(MainInner);
|
|
||||||
|
|
||||||
// ParseResult parseResult = rootCommand.Parse(inargs);
|
|
||||||
|
|
||||||
// CommandLineBuilder builder = new CommandLineBuilder(rootCommand);
|
|
||||||
|
|
||||||
// if (parseResult.Directives.Contains("local")) {
|
|
||||||
// builder.UseDefaults();
|
|
||||||
// } else {
|
|
||||||
// builder
|
|
||||||
// .UseParseErrorReporting()
|
|
||||||
// .UseExceptionHandler()
|
|
||||||
// .CancelOnProcessTermination();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return builder.Build().InvokeAsync(inargs);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static async Task MainInner(InvocationContext context)
|
|
||||||
// {
|
|
||||||
// bool verbose = context.ParseResult.GetValueForOption(Verbose);
|
|
||||||
// FileSystemInfo explicitSolutionPath = context.ParseResult.GetValueForOption(CsqSolutionPath);
|
|
||||||
// string explicitSquirrelVersion = context.ParseResult.GetValueForOption(CsqVersion);
|
|
||||||
|
|
||||||
// // we want to forward the --verbose argument to Squirrel, too.
|
|
||||||
// var verboseArgs = verbose ? new string[] { "--verbose" } : Array.Empty<string>();
|
|
||||||
// string[] restArgs = context.ParseResult.UnmatchedTokens
|
|
||||||
// .Concat(verboseArgs)
|
|
||||||
// .ToArray();
|
|
||||||
|
|
||||||
// if (verbose) {
|
|
||||||
// _logger.Level = LogLevel.Debug;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// context.Console.WriteLine($"Squirrel Locator 'csq' {SquirrelRuntimeInfo.SquirrelDisplayVersion}");
|
|
||||||
// _logger.Write($"Entry EXE: {SquirrelRuntimeInfo.EntryExePath}", LogLevel.Debug);
|
|
||||||
// CancellationToken cancellationToken = context.GetCancellationToken();
|
|
||||||
|
|
||||||
// await CheckForUpdates(cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
//#if DEBUG && false
|
|
||||||
// var devcsproj = Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "src", "Squirrel.CommandLine", "Squirrel.CommandLine.csproj");
|
|
||||||
// var devargs = new[] { "run", "--no-build", "-v", "q", "--project", devcsproj, "--" }.Concat(restArgs).ToArray();
|
|
||||||
// context.ExitCode = RunProcess("dotnet", devargs);
|
|
||||||
// return;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// var solutionDir = FindSolutionDirectory(explicitSolutionPath?.FullName);
|
|
||||||
// var nugetPackagesDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
|
||||||
// var cacheDir = Path.GetFullPath(solutionDir is null ? ".squirrel" : Path.Combine(solutionDir, ".squirrel"));
|
|
||||||
|
|
||||||
// Dictionary<string, string> packageSearchPaths = new();
|
|
||||||
// packageSearchPaths.Add("nuget user profile cache", Path.Combine(nugetPackagesDir, CLOWD_PACKAGE_NAME.ToLower(), "{0}", "tools"));
|
|
||||||
// if (solutionDir != null)
|
|
||||||
// packageSearchPaths.Add("visual studio packages cache", Path.Combine(solutionDir, "packages", CLOWD_PACKAGE_NAME + ".{0}", "tools"));
|
|
||||||
// packageSearchPaths.Add("squirrel cache", Path.Combine(cacheDir, "{0}", "tools"));
|
|
||||||
|
|
||||||
// async Task<int> runSquirrel(string version, CancellationToken cancellationToken)
|
|
||||||
// {
|
|
||||||
// foreach (var kvp in packageSearchPaths) {
|
|
||||||
// var path = String.Format(kvp.Value, version);
|
|
||||||
// if (Directory.Exists(path)) {
|
|
||||||
// _logger.Write($"Running {CLOWD_PACKAGE_NAME} {version} from {kvp.Key}", LogLevel.Info);
|
|
||||||
// return RunCsqFromPath(path, restArgs);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // we did not find it locally on first pass, search for the package online
|
|
||||||
// var dl = new NugetDownloader(_logger);
|
|
||||||
// var package = await dl.GetPackageMetadata(CLOWD_PACKAGE_NAME, version, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
// // search one more time now that we've potentially resolved the nuget version
|
|
||||||
// foreach (var kvp in packageSearchPaths) {
|
|
||||||
// var path = String.Format(kvp.Value, package.Identity.Version);
|
|
||||||
// if (Directory.Exists(path)) {
|
|
||||||
// _logger.Write($"Running {CLOWD_PACKAGE_NAME} {package.Identity.Version} from {kvp.Key}", LogLevel.Info);
|
|
||||||
// return RunCsqFromPath(path, restArgs);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // let's try to download it from NuGet.org
|
|
||||||
// var versionDir = Path.Combine(cacheDir, package.Identity.Version.ToString());
|
|
||||||
// Directory.CreateDirectory(cacheDir);
|
|
||||||
// Directory.CreateDirectory(versionDir);
|
|
||||||
|
|
||||||
// _logger.Write($"Downloading {package.Identity} from NuGet.", LogLevel.Info);
|
|
||||||
|
|
||||||
// var filePath = Path.Combine(versionDir, package.Identity + ".nupkg");
|
|
||||||
// using (var fs = File.Create(filePath)) {
|
|
||||||
// await dl.DownloadPackageToStream(package, fs, cancellationToken).ConfigureAwait(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// EasyZip.ExtractZipToDirectory(filePath, versionDir);
|
|
||||||
|
|
||||||
// var toolsPath = Path.Combine(versionDir, "tools");
|
|
||||||
// return RunCsqFromPath(toolsPath, restArgs);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (explicitSquirrelVersion != null) {
|
|
||||||
// context.ExitCode = await runSquirrel(explicitSquirrelVersion, cancellationToken).ConfigureAwait(false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (solutionDir is null) {
|
|
||||||
// throw new Exception($"Could not find '.sln'. Specify solution with '{CsqSolutionPath.Aliases.First()}=', or specify version of squirrel to use with '{CsqVersion.Aliases.First()}='.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// _logger.Write("Solution dir found at: " + solutionDir, LogLevel.Debug);
|
|
||||||
|
|
||||||
// // TODO actually read the SLN file rather than just searching for all .csproj files
|
|
||||||
// var dependencies = GetPackageVersionsFromDir(solutionDir, CLOWD_PACKAGE_NAME).Distinct().ToArray();
|
|
||||||
|
|
||||||
// if (dependencies.Length == 0) {
|
|
||||||
// throw new Exception($"{CLOWD_PACKAGE_NAME} nuget package was not found installed in solution.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (dependencies.Length > 1) {
|
|
||||||
// throw new Exception($"Found multiple versions of {CLOWD_PACKAGE_NAME} installed in solution ({string.Join(", ", dependencies)}). " +
|
|
||||||
// $"Please consolidate the following to a single version, or specify the version to use with '{CsqVersion.Aliases.First()}='");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var targetVersion = dependencies.Single();
|
|
||||||
|
|
||||||
// context.ExitCode = await runSquirrel(targetVersion, cancellationToken).ConfigureAwait(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static async Task CheckForUpdates(CancellationToken cancellationToken)
|
|
||||||
// {
|
|
||||||
// try {
|
|
||||||
// var myVer = SquirrelRuntimeInfo.SquirrelNugetVersion;
|
|
||||||
// var dl = new NugetDownloader(new NullNugetLogger());
|
|
||||||
// var package = await dl.GetPackageMetadata("csq", (myVer.IsPrerelease || myVer.HasMetadata) ? "pre" : "latest", cancellationToken).ConfigureAwait(false);
|
|
||||||
// if (package.Identity.Version > myVer)
|
|
||||||
// _logger.Write($"There is a new version of csq available ({package.Identity.Version})", LogLevel.Warn);
|
|
||||||
// } catch { }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static string FindSolutionDirectory(string slnArgument)
|
|
||||||
// {
|
|
||||||
// if (!String.IsNullOrWhiteSpace(slnArgument)) {
|
|
||||||
// if (File.Exists(slnArgument) && slnArgument.EndsWith(".sln", StringComparison.InvariantCultureIgnoreCase)) {
|
|
||||||
// // we were given a sln file as argument
|
|
||||||
// return Path.GetDirectoryName(Path.GetFullPath(slnArgument));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (Directory.Exists(slnArgument) && Directory.EnumerateFiles(slnArgument, "*.sln").Any()) {
|
|
||||||
// return Path.GetFullPath(slnArgument);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // try to find the solution directory from cwd
|
|
||||||
// var cwd = Environment.CurrentDirectory;
|
|
||||||
// var slnSearchDirs = new string[] {
|
|
||||||
// cwd,
|
|
||||||
// Path.Combine(cwd, ".."),
|
|
||||||
// Path.Combine(cwd, "..", ".."),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// return slnSearchDirs.FirstOrDefault(d => Directory.EnumerateFiles(d, "*.sln").Any());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static int RunCsqFromPath(string toolRootPath, string[] args)
|
|
||||||
// {
|
|
||||||
// // > v3.0.170
|
|
||||||
// if (File.Exists(Path.Combine(toolRootPath, "Squirrel.CommandLine.runtimeconfig.json"))) {
|
|
||||||
// var cliPath = Path.Combine(toolRootPath, "Squirrel.CommandLine.dll");
|
|
||||||
// var dnargs = new[] { cliPath }.Concat(args).ToArray();
|
|
||||||
// _logger.Write("running dotnet " + String.Join(" ", dnargs), LogLevel.Debug);
|
|
||||||
// return RunProcess("dotnet", dnargs);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // v3.0 - v3.0.170
|
|
||||||
// var toolDllPath = Path.Combine(toolRootPath, "csq.dll");
|
|
||||||
// if (File.Exists(toolDllPath)) {
|
|
||||||
// var dnargs = new[] { toolDllPath, "--csq-embedded" }.Concat(args).ToArray();
|
|
||||||
// _logger.Write("running dotnet " + String.Join(" ", dnargs), LogLevel.Debug);
|
|
||||||
// return RunProcess("dotnet", dnargs);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // < v3.0
|
|
||||||
// var toolExePath = Path.Combine(toolRootPath, "Squirrel.exe");
|
|
||||||
// if (File.Exists(toolExePath)) {
|
|
||||||
// if (!SquirrelRuntimeInfo.IsWindows)
|
|
||||||
// throw new NotSupportedException(
|
|
||||||
// $"Squirrel at '{toolRootPath}' does not support this operating system. Please update the package version to >= 3.0");
|
|
||||||
// _logger.Write("running " + toolExePath + " " + String.Join(" ", args), LogLevel.Debug);
|
|
||||||
// return RunProcess(toolExePath, args);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// throw new Exception("Unable to locate Squirrel at: " + toolRootPath);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static int RunProcess(string path, string[] args)
|
|
||||||
// {
|
|
||||||
// var p = Process.Start(path, args);
|
|
||||||
// p.WaitForExit();
|
|
||||||
// return p.ExitCode;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static IEnumerable<string> GetPackageVersionsFromDir(string rootDir, string packageName)
|
|
||||||
// {
|
|
||||||
// // old-style framework packages.config
|
|
||||||
// foreach (var packagesFile in EnumerateFilesUntilSpecificDepth(rootDir, "packages.config", 3)) {
|
|
||||||
// using var xmlStream = File.OpenRead(packagesFile);
|
|
||||||
// using var xmlReader = new XmlTextReader(xmlStream);
|
|
||||||
// var xdoc = XDocument.Load(xmlReader);
|
|
||||||
|
|
||||||
// var sqel = xdoc.Root?.Elements().FirstOrDefault(e => e.Attribute("id")?.Value == packageName);
|
|
||||||
// var ver = sqel?.Attribute("version");
|
|
||||||
// if (ver == null) continue;
|
|
||||||
|
|
||||||
// _logger.Write($"{packageName} {ver.Value} referenced in {packagesFile}", LogLevel.Debug);
|
|
||||||
|
|
||||||
// if (ver.Value.Contains('*'))
|
|
||||||
// throw new Exception(
|
|
||||||
// $"Wildcard versions are not supported in packages.config. Remove wildcard or upgrade csproj format to use PackageReference.");
|
|
||||||
|
|
||||||
// yield return ver.Value;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // new-style csproj PackageReference
|
|
||||||
// foreach (var projFile in EnumerateFilesUntilSpecificDepth(rootDir, "*.csproj", 3)) {
|
|
||||||
// var proj = ProjectRootElement.Open(projFile);
|
|
||||||
// if (proj == null) continue;
|
|
||||||
|
|
||||||
// ProjectItemElement item = proj.Items.FirstOrDefault(i => i.ItemType == "PackageReference" && i.Include == packageName);
|
|
||||||
// if (item == null) continue;
|
|
||||||
|
|
||||||
// var version = item.Children.FirstOrDefault(x => x.ElementName == "Version") as ProjectMetadataElement;
|
|
||||||
// if (version?.Value == null) continue;
|
|
||||||
|
|
||||||
// _logger.Write($"{packageName} {version.Value} referenced in {projFile}", LogLevel.Debug);
|
|
||||||
|
|
||||||
// yield return version.Value;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static IEnumerable<string> EnumerateFilesUntilSpecificDepth(string rootPath, string searchPattern, int maxDepth, int currentDepth = 0)
|
|
||||||
// {
|
|
||||||
// var files = Directory.EnumerateFiles(rootPath, searchPattern, SearchOption.TopDirectoryOnly);
|
|
||||||
// foreach (var f in files) {
|
|
||||||
// yield return f;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (currentDepth < maxDepth) {
|
|
||||||
// foreach (var dir in Directory.EnumerateDirectories(rootPath)) {
|
|
||||||
// foreach (var file in EnumerateFilesUntilSpecificDepth(dir, searchPattern, maxDepth, currentDepth + 1)) {
|
|
||||||
// yield return file;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -5,3 +5,4 @@ global using System.CommandLine.Parsing;
|
|||||||
global using System.IO;
|
global using System.IO;
|
||||||
global using System.Linq;
|
global using System.Linq;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
|
global using Microsoft.Extensions.Logging;
|
||||||
|
|||||||
@@ -3,33 +3,44 @@ using Serilog.Events;
|
|||||||
using Serilog;
|
using Serilog;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Squirrel.Csq.Commands;
|
using Squirrel.Csq.Commands;
|
||||||
using Squirrel.Deployment;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Squirrel.Csq.Updates;
|
||||||
|
using Squirrel.Csq.Compat;
|
||||||
|
|
||||||
namespace Squirrel.Csq;
|
namespace Squirrel.Csq;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static CliOption<string> TargetRuntime { get; }
|
public static CliOption<string> TargetRuntime { get; }
|
||||||
= new CliOption<string>("runtime", "-r", "--runtime", "The target runtime to build packages for.")
|
= new CliOption<string>("--runtime", "-r")
|
||||||
|
.SetDescription("The target runtime to build packages for.")
|
||||||
.SetArgumentHelpName("RID")
|
.SetArgumentHelpName("RID")
|
||||||
.MustBeSupportedRid()
|
.MustBeSupportedRid()
|
||||||
.SetRequired();
|
.SetRequired();
|
||||||
|
|
||||||
public static CliOption<bool> VerboseOption { get; }
|
public static CliOption<bool> VerboseOption { get; }
|
||||||
= new CliOption<bool>("--verbose", "Print diagnostic messages.");
|
= new CliOption<bool>("--verbose")
|
||||||
|
.SetDescription("Print diagnostic messages.");
|
||||||
|
|
||||||
public static Task<int> Main(string[] args)
|
private static CliOption<FileSystemInfo> CsqSolutionPath { get; }
|
||||||
|
= new CliOption<FileSystemInfo>("--solution")
|
||||||
|
.SetDescription("Explicit path to project solution (.sln)")
|
||||||
|
.AcceptExistingOnly();
|
||||||
|
|
||||||
|
private static IServiceProvider Provider { get; set; }
|
||||||
|
|
||||||
|
public static async Task<int> Main(string[] args)
|
||||||
{
|
{
|
||||||
CliRootCommand platformRootCommand = new CliRootCommand() {
|
CliRootCommand platformRootCommand = new CliRootCommand() {
|
||||||
TargetRuntime,
|
TargetRuntime,
|
||||||
VerboseOption,
|
VerboseOption,
|
||||||
|
CsqSolutionPath,
|
||||||
};
|
};
|
||||||
platformRootCommand.TreatUnmatchedTokensAsErrors = false;
|
platformRootCommand.TreatUnmatchedTokensAsErrors = false;
|
||||||
ParseResult parseResult = platformRootCommand.Parse(args);
|
ParseResult parseResult = platformRootCommand.Parse(args);
|
||||||
|
|
||||||
var runtime = RID.Parse(parseResult.GetValue(TargetRuntime) ?? SquirrelRuntimeInfo.SystemOs.GetOsShortName());
|
var runtime = RID.Parse(parseResult.GetValue(TargetRuntime) ?? SquirrelRuntimeInfo.SystemOs.GetOsShortName());
|
||||||
|
var solutionPath = parseResult.GetValue(CsqSolutionPath);
|
||||||
bool verbose = parseResult.GetValue(VerboseOption);
|
bool verbose = parseResult.GetValue(VerboseOption);
|
||||||
|
|
||||||
var builder = Host.CreateEmptyApplicationBuilder(new HostApplicationBuilderSettings {
|
var builder = Host.CreateEmptyApplicationBuilder(new HostApplicationBuilderSettings {
|
||||||
@@ -39,77 +50,68 @@ public class Program
|
|||||||
Configuration = new ConfigurationManager(),
|
Configuration = new ConfigurationManager(),
|
||||||
});
|
});
|
||||||
|
|
||||||
var minLevel = verbose ? LogEventLevel.Debug : LogEventLevel.Information;
|
builder.Services.AddSingleton<IRunnerFactory>(s => new RunnerFactory(s.GetRequiredService<Microsoft.Extensions.Logging.ILogger>(), solutionPath, s.GetRequiredService<IConfiguration>()));
|
||||||
|
builder.Configuration.AddEnvironmentVariables("CSQ_");
|
||||||
|
|
||||||
|
var minLevel = verbose ? LogEventLevel.Debug : LogEventLevel.Information;
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.MinimumLevel.Is(minLevel)
|
.MinimumLevel.Is(minLevel)
|
||||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
||||||
.MinimumLevel.Override("System", LogEventLevel.Warning)
|
.MinimumLevel.Override("System", LogEventLevel.Warning)
|
||||||
.WriteTo.Console()
|
.WriteTo.Console()
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
||||||
builder.Logging.AddSerilog();
|
builder.Logging.AddSerilog();
|
||||||
|
|
||||||
var host = builder.Build();
|
var host = builder.Build();
|
||||||
|
var logger = host.Services.GetRequiredService<ILogger<Program>>();
|
||||||
|
Provider = host.Services;
|
||||||
|
|
||||||
var logger = host.Services.GetRequiredService<Microsoft.Extensions.Logging.ILogger<Program>>();
|
CliRootCommand rootCommand = new CliRootCommand($"Squirrel {SquirrelRuntimeInfo.SquirrelDisplayVersion} for creating and distributing Squirrel releases.") {
|
||||||
|
TargetRuntime,
|
||||||
CliRootCommand rootCommand = new CliRootCommand($"Squirrel {SquirrelRuntimeInfo.SquirrelDisplayVersion} for creating and distributing Squirrel releases.");
|
VerboseOption,
|
||||||
rootCommand.Options.Add(TargetRuntime);
|
CsqSolutionPath,
|
||||||
rootCommand.Options.Add(VerboseOption);
|
};
|
||||||
|
|
||||||
switch (runtime.BaseRID) {
|
switch (runtime.BaseRID) {
|
||||||
case RuntimeOs.Windows:
|
case RuntimeOs.Windows:
|
||||||
if (!SquirrelRuntimeInfo.IsWindows)
|
if (!SquirrelRuntimeInfo.IsWindows)
|
||||||
logger.Warn("Cross-compiling will cause some commands and options of Squirrel to be unavailable.");
|
logger.Warn("Cross-compiling will cause some commands and options of Squirrel to be unavailable.");
|
||||||
Add(rootCommand, new PackWindowsCommand(), Windows.Commands.Pack);
|
Add(rootCommand, new PackWindowsCommand(), nameof(ICommandRunner.ExecutePackWindows));
|
||||||
Add(rootCommand, new ReleasifyWindowsCommand(), Windows.Commands.Releasify);
|
Add(rootCommand, new ReleasifyWindowsCommand(), nameof(ICommandRunner.ExecuteReleasifyWindows));
|
||||||
break;
|
break;
|
||||||
case RuntimeOs.OSX:
|
case RuntimeOs.OSX:
|
||||||
if (!SquirrelRuntimeInfo.IsOSX)
|
if (!SquirrelRuntimeInfo.IsOSX)
|
||||||
throw new InvalidOperationException("Cannot create OSX packages on non-OSX platforms.");
|
throw new NotSupportedException("Cannot create OSX packages on non-OSX platforms.");
|
||||||
Add(rootCommand, new BundleOsxCommand(), OSX.Commands.Bundle);
|
Add(rootCommand, new BundleOsxCommand(), nameof(ICommandRunner.ExecuteBundleOsx));
|
||||||
Add(rootCommand, new ReleasifyOsxCommand(), OSX.Commands.Releasify);
|
Add(rootCommand, new ReleasifyOsxCommand(), nameof(ICommandRunner.ExecuteReleasifyOsx));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException("Unsupported OS platform: " + runtime.BaseRID.GetOsLongName());
|
throw new NotSupportedException("Unsupported OS platform: " + runtime.BaseRID.GetOsLongName());
|
||||||
}
|
}
|
||||||
|
|
||||||
CliCommand downloadCommand = new CliCommand("download", "Download's the latest release from a remote update source.");
|
CliCommand downloadCommand = new CliCommand("download", "Download's the latest release from a remote update source.");
|
||||||
Add(downloadCommand, new HttpDownloadCommand(), options => SimpleWebRepository.DownloadRecentPackages(options));
|
Add(downloadCommand, new HttpDownloadCommand(), nameof(ICommandRunner.ExecuteHttpDownload));
|
||||||
Add(downloadCommand, new S3DownloadCommand(), options => S3Repository.DownloadRecentPackages(options));
|
Add(downloadCommand, new S3DownloadCommand(), nameof(ICommandRunner.ExecuteS3Download));
|
||||||
Add(downloadCommand, new GitHubDownloadCommand(), options => GitHubRepository.DownloadRecentPackages(options));
|
Add(downloadCommand, new GitHubDownloadCommand(), nameof(ICommandRunner.ExecuteGithubDownload));
|
||||||
rootCommand.Add(downloadCommand);
|
rootCommand.Add(downloadCommand);
|
||||||
|
|
||||||
var uploadCommand = new CliCommand("upload", "Upload local package(s) to a remote update source.");
|
var uploadCommand = new CliCommand("upload", "Upload local package(s) to a remote update source.");
|
||||||
Add(uploadCommand, new S3UploadCommand(), options => S3Repository.UploadMissingPackages(options));
|
Add(uploadCommand, new S3UploadCommand(), nameof(ICommandRunner.ExecuteS3Upload));
|
||||||
Add(uploadCommand, new GitHubUploadCommand(), options => GitHubRepository.UploadMissingPackages(options));
|
Add(uploadCommand, new GitHubUploadCommand(), nameof(ICommandRunner.ExecuteGithubUpload));
|
||||||
rootCommand.Add(uploadCommand);
|
rootCommand.Add(uploadCommand);
|
||||||
|
|
||||||
var cli = new CliConfiguration(rootCommand);
|
var cli = new CliConfiguration(rootCommand);
|
||||||
|
return await cli.InvokeAsync(args);
|
||||||
return cli.InvokeAsync(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CliCommand Add<T>(CliCommand parent, T command, Action<T> execute)
|
private static CliCommand Add<T>(CliCommand parent, T command, string commandName)
|
||||||
where T : BaseCommand
|
|
||||||
{
|
|
||||||
command.SetAction((ctx) => {
|
|
||||||
command.SetProperties(ctx);
|
|
||||||
command.TargetRuntime = RID.Parse(ctx.GetValue(TargetRuntime));
|
|
||||||
execute(command);
|
|
||||||
});
|
|
||||||
parent.Subcommands.Add(command);
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CliCommand Add<T>(CliCommand parent, T command, Func<T, Task> execute)
|
|
||||||
where T : BaseCommand
|
where T : BaseCommand
|
||||||
{
|
{
|
||||||
command.SetAction((ctx, token) => {
|
command.SetAction((ctx, token) => {
|
||||||
command.SetProperties(ctx);
|
command.SetProperties(ctx);
|
||||||
command.TargetRuntime = RID.Parse(ctx.GetValue(TargetRuntime));
|
command.TargetRuntime = RID.Parse(ctx.GetValue(TargetRuntime));
|
||||||
return execute(command);
|
var factory = Provider.GetRequiredService<IRunnerFactory>();
|
||||||
|
return factory.CreateAndExecuteAsync(commandName, command);
|
||||||
});
|
});
|
||||||
parent.Subcommands.Add(command);
|
parent.Subcommands.Add(command);
|
||||||
return command;
|
return command;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
<Description>A .NET Core Tool that uses the Squirrel framework to create installers and update packages for dotnet applications.</Description>
|
<Description>A .NET Core Tool that uses the Squirrel framework to create installers and update packages for dotnet applications.</Description>
|
||||||
<PackageIcon>Clowd_200.png</PackageIcon>
|
<PackageIcon>Clowd_200.png</PackageIcon>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
|
<NoWarn>$(NoWarn);CA2007;CS8002</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
|
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.23407.1" />
|
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.23407.1" />
|
||||||
|
<PackageReference Include="System.Xml.XDocument" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.CommandLine;
|
|
||||||
using System.CommandLine.Parsing;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Squirrel.CommandLine.Commands;
|
|
||||||
using Squirrel.CommandLine.Sync;
|
|
||||||
using Squirrel.SimpleSplat;
|
|
||||||
|
|
||||||
namespace Squirrel.CommandLine
|
|
||||||
{
|
|
||||||
public class SquirrelHost
|
|
||||||
{
|
|
||||||
public static Option<string> TargetRuntime { get; }
|
|
||||||
= new Option<string>(new[] { "-r", "--runtime" }, "The target runtime to build packages for.")
|
|
||||||
.SetArgumentHelpName("RID")
|
|
||||||
.MustBeSupportedRid()
|
|
||||||
.SetRequired();
|
|
||||||
|
|
||||||
public static Option<bool> VerboseOption { get; }
|
|
||||||
= new Option<bool>("--verbose", "Print diagnostic messages.");
|
|
||||||
|
|
||||||
public static Option<string[]> AddSearchPathOption { get; }
|
|
||||||
= new Option<string[]>("--addSearchPath", "Add additional search directories when looking for helper exe's.")
|
|
||||||
.SetArgumentHelpName("DIR");
|
|
||||||
|
|
||||||
public static int Main(string[] args)
|
|
||||||
{
|
|
||||||
var logger = ConsoleLogger.RegisterLogger();
|
|
||||||
|
|
||||||
RootCommand platformRootCommand = new RootCommand() {
|
|
||||||
TargetRuntime,
|
|
||||||
VerboseOption,
|
|
||||||
AddSearchPathOption,
|
|
||||||
};
|
|
||||||
platformRootCommand.TreatUnmatchedTokensAsErrors = false;
|
|
||||||
|
|
||||||
ParseResult parseResult = platformRootCommand.Parse(args);
|
|
||||||
|
|
||||||
bool verbose = parseResult.GetValueForOption(VerboseOption);
|
|
||||||
if (parseResult.GetValueForOption(AddSearchPathOption) is { } searchPath) {
|
|
||||||
foreach (var v in searchPath) {
|
|
||||||
HelperFile.AddSearchPath(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RootCommand rootCommand = new RootCommand($"Squirrel {SquirrelRuntimeInfo.SquirrelDisplayVersion} for creating and distributing Squirrel releases.");
|
|
||||||
rootCommand.AddGlobalOption(TargetRuntime);
|
|
||||||
rootCommand.AddGlobalOption(VerboseOption);
|
|
||||||
rootCommand.AddGlobalOption(AddSearchPathOption);
|
|
||||||
|
|
||||||
var runtime = RID.Parse(parseResult.GetValueForOption(TargetRuntime) ?? SquirrelRuntimeInfo.SystemOs.GetOsShortName());
|
|
||||||
|
|
||||||
switch (runtime.BaseRID) {
|
|
||||||
case RuntimeOs.Windows:
|
|
||||||
if (!SquirrelRuntimeInfo.IsWindows)
|
|
||||||
logger.Write("Cross-compiling will cause some commands and options of Squirrel to be unavailable.", LogLevel.Warn);
|
|
||||||
Add(rootCommand, new PackWindowsCommand(), Windows.Commands.Pack);
|
|
||||||
Add(rootCommand, new ReleasifyWindowsCommand(), Windows.Commands.Releasify);
|
|
||||||
|
|
||||||
// temporarily, upload only supports windows.
|
|
||||||
Command uploadCommand = new Command("upload", "Upload local package(s) to a remote update source.");
|
|
||||||
Add(uploadCommand, new S3UploadCommand(), options => S3Repository.UploadMissingPackages(options));
|
|
||||||
Add(uploadCommand, new GitHubUploadCommand(), options => GitHubRepository.UploadMissingPackages(options));
|
|
||||||
rootCommand.Add(uploadCommand);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case RuntimeOs.OSX:
|
|
||||||
if (!SquirrelRuntimeInfo.IsOSX)
|
|
||||||
logger.Write("Cross-compiling will cause some commands and options of Squirrel to be unavailable.", LogLevel.Warn);
|
|
||||||
Add(rootCommand, new BundleOsxCommand(), OSX.Commands.Bundle);
|
|
||||||
Add(rootCommand, new ReleasifyOsxCommand(), OSX.Commands.Releasify);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException("Unsupported OS platform: " + runtime.BaseRID.GetOsLongName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
logger.Level = LogLevel.Debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command downloadCommand = new Command("download", "Download's the latest release from a remote update source.");
|
|
||||||
Add(downloadCommand, new HttpDownloadCommand(), options => SimpleWebRepository.DownloadRecentPackages(options));
|
|
||||||
Add(downloadCommand, new S3DownloadCommand(), options => S3Repository.DownloadRecentPackages(options));
|
|
||||||
Add(downloadCommand, new GitHubDownloadCommand(), options => GitHubRepository.DownloadRecentPackages(options));
|
|
||||||
rootCommand.Add(downloadCommand);
|
|
||||||
|
|
||||||
return rootCommand.Invoke(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Command Add<T>(Command parent, T command, Action<T> execute)
|
|
||||||
where T : BaseCommand
|
|
||||||
{
|
|
||||||
command.SetHandler((ctx) => {
|
|
||||||
command.SetProperties(ctx.ParseResult);
|
|
||||||
command.TargetRuntime = RID.Parse(ctx.ParseResult.GetValueForOption(TargetRuntime));
|
|
||||||
execute(command);
|
|
||||||
});
|
|
||||||
parent.AddCommand(command);
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Command Add<T>(Command parent, T command, Func<T, Task> execute)
|
|
||||||
where T : BaseCommand
|
|
||||||
{
|
|
||||||
command.SetHandler((ctx) => {
|
|
||||||
command.SetProperties(ctx.ParseResult);
|
|
||||||
command.TargetRuntime = RID.Parse(ctx.ParseResult.GetValueForOption(TargetRuntime));
|
|
||||||
return execute(command);
|
|
||||||
});
|
|
||||||
parent.AddCommand(command);
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
69
src/Squirrel.Csq/Updates/NugetDownloader.cs
Normal file
69
src/Squirrel.Csq/Updates/NugetDownloader.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using NuGet.Configuration;
|
||||||
|
using NuGet.Packaging.Core;
|
||||||
|
using NuGet.Protocol.Core.Types;
|
||||||
|
using NuGet.Versioning;
|
||||||
|
using NugetLogger = NuGet.Common.ILogger;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Updates;
|
||||||
|
|
||||||
|
public class NugetDownloader
|
||||||
|
{
|
||||||
|
private readonly NugetLogger _logger;
|
||||||
|
private readonly PackageSource _packageSource;
|
||||||
|
private readonly SourceRepository _sourceRepository;
|
||||||
|
private readonly SourceCacheContext _sourceCacheContext;
|
||||||
|
|
||||||
|
public NugetDownloader(NugetLogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_packageSource = new PackageSource("https://api.nuget.org/v3/index.json", "NuGet.org");
|
||||||
|
_sourceRepository = new SourceRepository(_packageSource, Repository.Provider.GetCoreV3());
|
||||||
|
_sourceCacheContext = new SourceCacheContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IPackageSearchMetadata> GetPackageMetadata(string packageName, string version, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
PackageMetadataResource packageMetadataResource = _sourceRepository.GetResource<PackageMetadataResource>();
|
||||||
|
FindPackageByIdResource packageByIdResource = _sourceRepository.GetResource<FindPackageByIdResource>();
|
||||||
|
IPackageSearchMetadata package = null;
|
||||||
|
|
||||||
|
var prerelease = version?.Equals("pre", StringComparison.InvariantCultureIgnoreCase) == true;
|
||||||
|
if (version is null || version.Equals("latest", StringComparison.InvariantCultureIgnoreCase) || prerelease) {
|
||||||
|
// get latest (or prerelease) version
|
||||||
|
IEnumerable<IPackageSearchMetadata> metadata = await packageMetadataResource
|
||||||
|
.GetMetadataAsync(packageName, true, true, _sourceCacheContext, _logger, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
package = metadata
|
||||||
|
.Where(x => x.IsListed)
|
||||||
|
.Where(x => prerelease || !x.Identity.Version.IsPrerelease)
|
||||||
|
.OrderByDescending(x => x.Identity.Version)
|
||||||
|
.FirstOrDefault();
|
||||||
|
} else {
|
||||||
|
// resolve version ranges and wildcards
|
||||||
|
var versions = await packageByIdResource.GetAllVersionsAsync(packageName, _sourceCacheContext, _logger, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
var resolved = versions.FindBestMatch(VersionRange.Parse(version), version => version);
|
||||||
|
|
||||||
|
// get exact version
|
||||||
|
var packageIdentity = new PackageIdentity(packageName, resolved);
|
||||||
|
package = await packageMetadataResource
|
||||||
|
.GetMetadataAsync(packageIdentity, _sourceCacheContext, _logger, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (package is null) {
|
||||||
|
throw new Exception($"Unable to locate {packageName} {version} on NuGet.org");
|
||||||
|
}
|
||||||
|
|
||||||
|
return package;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DownloadPackageToStream(IPackageSearchMetadata package, Stream targetStream, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
FindPackageByIdResource packageByIdResource = _sourceRepository.GetResource<FindPackageByIdResource>();
|
||||||
|
await packageByIdResource
|
||||||
|
.CopyNupkgToStreamAsync(package.Identity.Id, package.Identity.Version, targetStream, _sourceCacheContext, _logger, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/Squirrel.Csq/Updates/NullNugetLogger.cs
Normal file
54
src/Squirrel.Csq/Updates/NullNugetLogger.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using NugetLevel = NuGet.Common.LogLevel;
|
||||||
|
using NugetLogger = NuGet.Common.ILogger;
|
||||||
|
using NugetMessage = NuGet.Common.ILogMessage;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Updates;
|
||||||
|
|
||||||
|
class NullNugetLogger : NugetLogger
|
||||||
|
{
|
||||||
|
void NugetLogger.LogDebug(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogVerbose(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogInformation(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogMinimal(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogWarning(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogError(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.LogInformationSummary(string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.Log(NugetLevel level, string data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Task NugetLogger.LogAsync(NugetLevel level, string data)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NugetLogger.Log(NugetMessage message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Task NugetLogger.LogAsync(NugetMessage message)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Squirrel.Csq/Updates/UpdateChecker.cs
Normal file
28
src/Squirrel.Csq/Updates/UpdateChecker.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using Squirrel.Packaging;
|
||||||
|
|
||||||
|
namespace Squirrel.Csq.Updates;
|
||||||
|
|
||||||
|
public class UpdateChecker
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public UpdateChecker(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CheckForUpdates()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
var cancel = new CancellationTokenSource(3000);
|
||||||
|
var myVer = SquirrelRuntimeInfo.SquirrelNugetVersion;
|
||||||
|
var dl = new NugetDownloader(new NugetLoggingWrapper(_logger));
|
||||||
|
var package = await dl.GetPackageMetadata("csq", (myVer.IsPrerelease || myVer.HasMetadata) ? "pre" : "latest", cancel.Token).ConfigureAwait(false);
|
||||||
|
if (package.Identity.Version > myVer)
|
||||||
|
_logger.Warn($"There is a new version of csq available ({package.Identity.Version})");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
_logger.Debug(ex, "Failed to check for updates.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
|
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
|
||||||
"version": "3.0",
|
"version": "4.0",
|
||||||
"gitCommitIdShortFixedLength": 7,
|
"gitCommitIdShortFixedLength": 7,
|
||||||
"publicReleaseRefSpec": [
|
"publicReleaseRefSpec": [
|
||||||
"^refs/heads/master$"
|
"^refs/heads/master$"
|
||||||
|
|||||||
Reference in New Issue
Block a user