Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions Squirrel.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionLevel", "SolutionLevel", "{ED657D2C-F8A0-4012-A64F-7367D41BE4D2}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
build.ps1 = build.ps1
.github\workflows\build.yml = .github\workflows\build.yml
src\Directory.Build.props = src\Directory.Build.props
Squirrel.entitlements = Squirrel.entitlements
vendor\wix\template.wxs = vendor\wix\template.wxs
version.json = version.json
.github\workflows\build.yml = .github\workflows\build.yml
build.ps1 = build.ps1
Squirrel.entitlements = Squirrel.entitlements
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Setup", "src\Setup\Setup.vcxproj", "{6B406985-B2E1-4FED-A405-BD0694D68E93}"
Expand All @@ -26,14 +26,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squirrel.CommandLine", "src
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StubExecutable", "src\StubExecutable\StubExecutable.vcxproj", "{611A03D4-4CDE-4DA0-B151-DE6FAFFB8B8C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update.OSX", "src\Update.OSX\Update.OSX.csproj", "{A63B2CDA-5ECC-461C-9B1F-54CF4709ACBD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Update.OSX", "src\Update.OSX\Update.OSX.csproj", "{A63B2CDA-5ECC-461C-9B1F-54CF4709ACBD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squirrel.Tool", "src\Squirrel.Tool\Squirrel.Tool.csproj", "{9E769C7E-A54C-4844-8362-727D37BB1578}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squirrel.Tool", "src\Squirrel.Tool\Squirrel.Tool.csproj", "{9E769C7E-A54C-4844-8362-727D37BB1578}"
ProjectSection(ProjectDependencies) = postProject
{6B406985-B2E1-4FED-A405-BD0694D68E93} = {6B406985-B2E1-4FED-A405-BD0694D68E93}
{611A03D4-4CDE-4DA0-B151-DE6FAFFB8B8C} = {611A03D4-4CDE-4DA0-B151-DE6FAFFB8B8C}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squirrel.CommandLine.Tests", "test\Squirrel.CommandLine.Tests\Squirrel.CommandLine.Tests.csproj", "{519EAB50-47B8-425F-8B20-AB9548F220B4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -72,6 +74,10 @@ Global
{9E769C7E-A54C-4844-8362-727D37BB1578}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E769C7E-A54C-4844-8362-727D37BB1578}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E769C7E-A54C-4844-8362-727D37BB1578}.Release|Any CPU.Build.0 = Release|Any CPU
{519EAB50-47B8-425F-8B20-AB9548F220B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{519EAB50-47B8-425F-8B20-AB9548F220B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{519EAB50-47B8-425F-8B20-AB9548F220B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{519EAB50-47B8-425F-8B20-AB9548F220B4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
27 changes: 27 additions & 0 deletions src/Squirrel.CommandLine/BaseCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using Squirrel.SimpleSplat;

namespace Squirrel.CommandLine
{
public class BaseCommand : Command
{
protected static IFullLogger Log = SquirrelLocator.CurrentMutable.GetService<ILogManager>().GetLogger(typeof(BaseOptions));

public Option<DirectoryInfo> ReleaseDirectory { get; }
protected BaseCommand(string name, string description)
: base(name, description)
{
ReleaseDirectory = new Option<DirectoryInfo>(new[] { "-r", "--releaseDir" }, "Output {DIRECTORY} for releasified packages") {
ArgumentHelpName = "DIRECTORY"
};
Add(ReleaseDirectory);
}

private protected void SetOptionsValues(InvocationContext context, BaseOptions options)
{
options.releaseDir = context.ParseResult.GetValueForOption(ReleaseDirectory)?.FullName;
}
}
}
9 changes: 9 additions & 0 deletions src/Squirrel.CommandLine/Bitness.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Squirrel.CommandLine
{
public enum Bitness
{
Unknown,
x86,
x64
}
}
105 changes: 105 additions & 0 deletions src/Squirrel.CommandLine/Deployment/GitHubCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System.CommandLine;
using Squirrel.CommandLine.Sync;
using System.CommandLine.Invocation;
using System.Threading.Tasks;
using System;

namespace Squirrel.CommandLine.Deployment
{
public class GitHubCommand : Command
{
public GitHubCommand() : base("github", "Upload or download from GitHub")
{
Add(new GitHubDownloadCommand());
Add(new GitHubUploadCommand());
}
}

public class GitHubBaseCommand : BaseCommand
{
public Option<Uri> RepoUrl { get; }
public Option<string> Token { get; }

protected GitHubBaseCommand(string name, string description)
: base(name, description)
{
RepoUrl = new Option<Uri>("--repoUrl", "Full url to the github repository\nexample: 'https://github.com/myname/myrepo'") {
IsRequired = true
};
RepoUrl.MustBeValidHttpUri();
Add(RepoUrl);

Token = new Option<string>("--token", "OAuth token to use as login credentials");
Add(Token);
}

private protected void SetOptionsValues(InvocationContext context, SyncGithubOptions options)
{
base.SetOptionsValues(context, options);
options.repoUrl = context.ParseResult.GetValueForOption(RepoUrl)?.AbsoluteUri;
options.token = context.ParseResult.GetValueForOption(Token);
}
}

public class GitHubDownloadCommand : GitHubBaseCommand
{
public Option<bool> Pre { get; }

public GitHubDownloadCommand()
: base("down", "Download latest release from GitHub")
{
Pre = new Option<bool>("--pre", "Get latest pre-release instead of stable");
Add(Pre);

this.SetHandler(Execute);
}

private protected new void SetOptionsValues(InvocationContext context, SyncGithubOptions options)
{
base.SetOptionsValues(context, options);
options.pre = context.ParseResult.GetValueForOption(Pre);
}

private async Task Execute(InvocationContext context)
{
SyncGithubOptions options = new();
SetOptionsValues(context, options);
await new GitHubRepository(options).DownloadRecentPackages();
}
}

public class GitHubUploadCommand : GitHubBaseCommand
{
public Option<bool> Publish { get; }
public Option<string> ReleaseName { get; }

public GitHubUploadCommand()
: base("up", "Upload latest release to GitHub")
{
Publish = new Option<bool>("--publish", "Publish release instead of creating draft");
Add(Publish);

ReleaseName = new Option<string>("--releaseName", "A custom {NAME} for created release") {
ArgumentHelpName = "NAME"
};
Add(ReleaseName);

this.SetHandler(Execute);
}

//Intentionally hiding base member
private protected new void SetOptionsValues(InvocationContext context, SyncGithubOptions options)
{
base.SetOptionsValues(context, options);
options.publish = context.ParseResult.GetValueForOption(Publish);
options.releaseName = context.ParseResult.GetValueForOption(ReleaseName);
}

private async Task Execute(InvocationContext context)
{
SyncGithubOptions options = new();
SetOptionsValues(context, options);
await new GitHubRepository(options).UploadMissingPackages();
}
}
}
47 changes: 47 additions & 0 deletions src/Squirrel.CommandLine/Deployment/HttpCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Threading.Tasks;
using Squirrel.CommandLine.Sync;

namespace Squirrel.CommandLine.Deployment
{
public class HttpCommand : Command
{
public HttpCommand() : base("http", "Download from HTTP")
{
Add(new HttpDownloadCommand());
}
}

public class HttpDownloadCommand : BaseCommand
{
public Option<Uri> Url { get; }

public HttpDownloadCommand()
: base("down", "Download latest release from HTTP")
{
Url = new Option<Uri>("--url", "URL to download from") {
ArgumentHelpName = "URL",
IsRequired = true,
};
Url.MustBeValidHttpUri();
Add(Url);

this.SetHandler(Execute);
}

private protected void SetOptionsValues(InvocationContext context, SyncHttpOptions options)
{
base.SetOptionsValues(context, options);
options.url = context.ParseResult.GetValueForOption(Url)?.AbsoluteUri;
}

public async Task Execute(InvocationContext context)
{
SyncHttpOptions options = new();
SetOptionsValues(context, options);
await new SimpleWebRepository(options).DownloadRecentPackages();
}
}
}
141 changes: 141 additions & 0 deletions src/Squirrel.CommandLine/Deployment/S3Commands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Threading.Tasks;
using Squirrel.CommandLine.Sync;

namespace Squirrel.CommandLine.Deployment
{
public class S3Command : Command
{
public S3Command() : base("s3", "Upload or download from S3 API")
{
Add(new S3DownloadCommand());
Add(new S3UploadCommand());
}
}

public class S3BaseCommand : BaseCommand
{
public Option<string> KeyId { get; }
public Option<string> Secret { get; }
public Option<string> Region { get; }
public Option<string> Endpoint { get; }
public Option<string> Bucket { get; }
public Option<string> PathPrefix { get; }

protected S3BaseCommand(string name, string description)
: base(name, description)
{
KeyId = new Option<string>("--keyId", "Authentication {IDENTIFIER} or access key") {
ArgumentHelpName = "IDENTIFIER",
IsRequired = true
};
Add(KeyId);

Secret = new Option<string>("--secret", "Authentication secret {KEY}") {
ArgumentHelpName = "KEY",
IsRequired = true
};
Add(Secret);

Region = new Option<string>("--region", "AWS service {REGION} (eg. us-west-1)") {
ArgumentHelpName = "REGION"
};
Region.AddValidator(result => {
for (var i = 0; i < result.Tokens.Count; i++) {
var region = result.Tokens[i].Value;
if (!string.IsNullOrWhiteSpace(region)) {
var r = Amazon.RegionEndpoint.GetBySystemName(result.Tokens[0].Value);
if (r is null || r.DisplayName == "Unknown") {
result.ErrorMessage = $"Region '{region}' lookup failed, is this a valid AWS region?";
}
} else {
result.ErrorMessage = "A region value is required";
}
}
});
Add(Region);

Endpoint = new Option<string>("--endpoint", "Custom service {URL} (backblaze, digital ocean, etc)") {
ArgumentHelpName = "URL"
};
Add(Endpoint);

Bucket = new Option<string>("--bucket", "{NAME} of the S3 bucket") {
ArgumentHelpName = "NAME",
IsRequired = true
};
Add(Bucket);

PathPrefix = new Option<string>("--pathPrefix", "A sub-folder {PATH} used for files in the bucket, for creating release channels (eg. 'stable' or 'dev')") {
ArgumentHelpName = "PATH"
};
Add(PathPrefix);

this.AreMutuallyExclusive(Region, Endpoint)
.AtLeastOneRequired(Region, Endpoint);
}

private protected void SetOptionsValues(InvocationContext context, SyncS3Options options)
{
base.SetOptionsValues(context, options);
options.keyId = context.ParseResult.GetValueForOption(KeyId);
options.secret = context.ParseResult.GetValueForOption(Secret);
options.region = context.ParseResult.GetValueForOption(Region);
options.endpoint = context.ParseResult.GetValueForOption(Endpoint);
options.bucket = context.ParseResult.GetValueForOption(Bucket);
options.pathPrefix = context.ParseResult.GetValueForOption(PathPrefix);
}
}

public class S3DownloadCommand : S3BaseCommand
{
public S3DownloadCommand()
: base("down", "Download latest release from S3 API")
{
this.SetHandler(Execute);
}

private async Task Execute(InvocationContext context)
{
SyncS3Options options = new();
SetOptionsValues(context, options);
await new S3Repository(options).DownloadRecentPackages();
}
}

public class S3UploadCommand : S3BaseCommand
{
public Option<bool> Overwrite { get; }
public Option<int> KeepMaxReleases { get; }

public S3UploadCommand()
: base("up", "Upload releases to S3 API")
{
Overwrite = new Option<bool>("--overwrite", "Replace existing files if source has changed");
Add(Overwrite);

KeepMaxReleases = new Option<int>("--keepMaxReleases", "Applies a retention policy during upload which keeps only the specified {NUMBER} of old versions") {
ArgumentHelpName = "NUMBER"
};
Add(KeepMaxReleases);

this.SetHandler(Execute);
}

//Intentionally hiding base member
private protected new void SetOptionsValues(InvocationContext context, SyncS3Options options)
{
base.SetOptionsValues(context, options);
options.overwrite = context.ParseResult.GetValueForOption(Overwrite);
options.keepMaxReleases = context.ParseResult.GetValueForOption(KeepMaxReleases);
}

private async Task Execute(InvocationContext context)
{
SyncS3Options options = new();
SetOptionsValues(context, options);
await new S3Repository(options).UploadMissingPackages();
}
}
}
Loading