wip
This commit is contained in:
commit
03ebf47b9f
33 changed files with 1657 additions and 0 deletions
105
src/core.next/Commands/Checkout.cs
Normal file
105
src/core.next/Commands/Checkout.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) The Geekeey Authors
|
||||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text;
|
||||
|
||||
namespace Geekeey.Actions.Core.Commands;
|
||||
|
||||
internal sealed class Checkout : Command
|
||||
{
|
||||
#pragma warning disable format // @formatter:off
|
||||
private static readonly Option<Uri> Repository = new("--repository") { Required = true };
|
||||
private static readonly Option<DirectoryInfo> Destination = new("--path") { Required = true };
|
||||
private static readonly Option<string> Reference = new("--reference") { Required = true };
|
||||
#pragma warning restore format // @formatter:on
|
||||
|
||||
internal Checkout() : base("checkout")
|
||||
{
|
||||
Add(Repository);
|
||||
Add(Destination);
|
||||
Add(Reference);
|
||||
|
||||
SetAction(HandleAsync);
|
||||
}
|
||||
|
||||
private async Task<int> HandleAsync(ParseResult result, CancellationToken cancellationToken)
|
||||
{
|
||||
var server = result.GetRequiredValue(Program.Server);
|
||||
var access = result.GetRequiredValue(Program.Token);
|
||||
|
||||
var workspace = result.GetRequiredValue(Destination);
|
||||
|
||||
await $"git init -q {workspace.FullName}";
|
||||
await $"git -C {workspace.FullName} config set --local protocol.version 2";
|
||||
await $"git -C {workspace.FullName} config set --local gc.auto 0";
|
||||
|
||||
var repository = result.GetRequiredValue(Repository);
|
||||
|
||||
if (!repository.IsAbsoluteUri)
|
||||
{
|
||||
// relative repository urls are resolved against the server url
|
||||
repository = new Uri(server, repository);
|
||||
|
||||
await $"git -C {workspace.FullName} config set --local --append url.{repository}.insteadOf git@{repository.Host}";
|
||||
await $"git -C {workspace.FullName} config set --local --append url.{repository}.insteadOf ssh://git@{repository.Host}";
|
||||
await $"git -C {workspace.FullName} config set --local --append url.{repository}.insteadOf git://{repository.Host}";
|
||||
|
||||
var header = $"Authorization: Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes($"x-access-token::${access}"))}";
|
||||
await $"git -C {workspace.FullName} config set --local http.{repository}.extraheader '{header}'";
|
||||
}
|
||||
|
||||
var origin = "origin";
|
||||
var reference = result.GetRequiredValue(Reference);
|
||||
|
||||
await $"git -C {workspace.FullName} remote add {origin} {repository}";
|
||||
var list = (await $"git -C {workspace.FullName} ls-remote {origin} {reference}").Split('\t');
|
||||
|
||||
if (list.Length < 2)
|
||||
{
|
||||
throw new InvalidOperationException("git ls-remote resolved nothing");
|
||||
}
|
||||
|
||||
var @sha = list[0].Trim();
|
||||
var @ref = list[1].Trim();
|
||||
|
||||
if (@ref.TryCutPrefix("refs/heads/", out var name))
|
||||
{
|
||||
var remote = $"refs/remotes/{origin}/{name}";
|
||||
var branch = name;
|
||||
|
||||
await $"git -C {workspace.FullName} fetch --no-tags --prune --no-recurse-submodules --depth=1 {origin} +{@sha}:{remote}";
|
||||
await $"git -C {workspace.FullName} checkout --force -B {branch} {remote}";
|
||||
}
|
||||
else if (@ref.TryCutPrefix("refs/pull/", out name))
|
||||
{
|
||||
var remote = $"refs/remotes/pull/{name}";
|
||||
|
||||
// Best-effort parity with the Go code's env.BaseRef/env.HeadRef:
|
||||
var baseRef = Environment.GetEnvironmentVariable("GITHUB_BASE_REF");
|
||||
var headRef = Environment.GetEnvironmentVariable("GITHUB_HEAD_REF");
|
||||
|
||||
var branch =
|
||||
!string.IsNullOrEmpty(baseRef) ? baseRef :
|
||||
!string.IsNullOrEmpty(headRef) ? headRef :
|
||||
throw new InvalidOperationException("pull request can not find base ref for branch");
|
||||
|
||||
await $"git -C {workspace.FullName} fetch --no-tags --prune --no-recurse-submodules --depth=1 {origin} +{@sha}:{remote}";
|
||||
await $"git -C {workspace.FullName} checkout --force -B {branch} {branch}";
|
||||
}
|
||||
else if (@ref.TryCutPrefix("refs/tags/", out name))
|
||||
{
|
||||
var remote = $"refs/tags/{name}";
|
||||
|
||||
await $"git -C {workspace.FullName} fetch --no-tags --prune --no-recurse-submodules --depth=1 {origin} +{@sha}:{remote}";
|
||||
await $"git -C {workspace.FullName} checkout --force {remote}";
|
||||
}
|
||||
else
|
||||
{
|
||||
await $"git -C {workspace.FullName} fetch --no-tags --prune --no-recurse-submodules --depth=1 {origin} {@ref}";
|
||||
await $"git -C {workspace.FullName} checkout --force {@ref}";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue