public async Task FailedGetRepoTargetReturnsFailure(
     IGitRepository repo,
     GitPatcherVersioning patcherVersioning,
     CancellationToken cancel,
     ResetToTarget sut)
 {
     sut.GetRepoTarget.Get(default !, default !).ReturnsForAnyArgs(GetResponse <RepoTarget> .Failure);
Beispiel #2
0
        public GetResponse <ResetResults> Reset(
            IGitRepository repo,
            GitPatcherVersioning patcherVersioning,
            CancellationToken cancel)
        {
            CheckoutRunnerBranch.Checkout(repo);

            var targets = GetRepoTarget.Get(
                repo,
                patcherVersioning);

            if (targets.Failed)
            {
                return(targets.BubbleFailure <ResetResults>());
            }

            var commit = RetrieveCommit.TryGet(
                repo,
                targets.Value,
                patcherVersioning,
                cancel);

            if (commit.Failed)
            {
                return(commit.BubbleFailure <ResetResults>());
            }

            cancel.ThrowIfCancellationRequested();

            _logger.Information("Checking out {TargetSha}", targets.Value.TargetSha);
            repo.ResetHard(commit.Value);

            return(new ResetResults(targets.Value, commit.Value.CommitMessage, commit.Value.CommitDate));
        }
Beispiel #3
0
        public GetResponse <ICommit> TryGet(
            IGitRepository repo,
            RepoTarget targets,
            GitPatcherVersioning patcherVersioning,
            CancellationToken cancel)
        {
            var commit = repo.TryGetCommit(targets.TargetSha, out var validSha);

            if (!validSha)
            {
                return(GetResponse <ICommit> .Fail("Malformed sha string"));
            }

            cancel.ThrowIfCancellationRequested();
            if (commit == null)
            {
                bool fetchIfMissing = ShouldFetchIfMissing.Should(patcherVersioning);
                if (!fetchIfMissing)
                {
                    return(GetResponse <ICommit> .Fail("Could not locate commit with given sha"));
                }
                repo.Fetch();
                commit = repo.TryGetCommit(targets.TargetSha, out _);
                if (commit == null)
                {
                    return(GetResponse <ICommit> .Fail("Could not locate commit with given sha"));
                }
            }

            return(GetResponse <ICommit> .Succeed(commit));
        }
Beispiel #4
0
        public async Task BranchNewContent()
        {
            using var repoPath = GetRepository(out var remote, out var local);
            string tipSha;
            string commitSha;

            var clonePath = Path.Combine(repoPath.Dir.Path, "Clone");

            using var clone = new Repository(Repository.Clone(remote, clonePath));

            {
                using var repo = new Repository(local);
                tipSha         = repo.Head.Tip.Sha;
                commitSha      = AddACommit(local).Sha;
                repo.Head.Tip.Sha.Should().NotBeEquivalentTo(tipSha);
                repo.Network.Push(repo.Branches[DefaultBranch]);
            }

            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Branch, DefaultBranch);
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : clonePath,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeFalse();
            resp.RunnableState.Succeeded.Should().BeTrue();
            clone.Head.Tip.Sha.Should().BeEquivalentTo(commitSha);
            clone.Head.FriendlyName.Should().BeEquivalentTo(GitPatcherRun.RunnerBranch);
            clone.Branches[DefaultBranch].Tip.Sha.Should().BeEquivalentTo(tipSha);
        }
Beispiel #5
0
 public bool Should(GitPatcherVersioning patcherVersioning)
 {
     return(patcherVersioning.Versioning switch
     {
         PatcherVersioningEnum.Commit => true,
         _ => false
     });
Beispiel #6
0
        public async Task BranchTargetJumpback()
        {
            using var repoPath = GetRepository(out var remote, out var local);
            using var repo     = new Repository(local);
            var tipSha   = repo.Head.Tip.Sha;
            var jbName   = "Jumpback";
            var jbBranch = repo.CreateBranch(jbName);

            repo.Branches.Update(
                jbBranch,
                b => b.Remote         = repo.Network.Remotes.First().Name,
                b => b.UpstreamBranch = jbBranch.CanonicalName);
            repo.Network.Push(jbBranch);

            var commit = AddACommit(local);

            repo.Head.Tip.Sha.Should().NotBeEquivalentTo(tipSha);

            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Branch, jbName);
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : local,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeFalse();
            resp.RunnableState.Succeeded.Should().BeTrue();
            repo.Head.Tip.Sha.Should().BeEquivalentTo(tipSha);
            repo.Head.FriendlyName.Should().BeEquivalentTo(GitPatcherRun.RunnerBranch);
            repo.Branches[jbName].Tip.Sha.Should().BeEquivalentTo(tipSha);
            repo.Branches[DefaultBranch].Tip.Sha.Should().BeEquivalentTo(commit.Sha);
        }
Beispiel #7
0
        public async Task TagTargetNewContent()
        {
            using var repoPath = GetRepository(out var remote, out var local);

            var clonePath = Path.Combine(repoPath.Dir.Path, "Clone");

            using var clone = new Repository(Repository.Clone(remote, clonePath));

            var    tagStr = "1.3.4";
            string commitSha;
            {
                using var repo = new Repository(local);
                AddACommit(local);
                commitSha = repo.Head.Tip.Sha;
                var tag = repo.Tags.Add(tagStr, commitSha);
                repo.Network.Push(repo.Network.Remotes.First(), tag.CanonicalName);
            }

            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Tag, tagStr);
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : clonePath,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeFalse();
            resp.RunnableState.Succeeded.Should().BeTrue();
            clone.Head.Tip.Sha.Should().BeEquivalentTo(commitSha);
            clone.Head.FriendlyName.Should().BeEquivalentTo(GitPatcherRun.RunnerBranch);
        }
Beispiel #8
0
        public async Task TagTargetJumpback()
        {
            using var repoPath = GetRepository(out var remote, out var local);
            var tag = "1.3.4";

            using var repo = new Repository(local);
            var tipSha = repo.Head.Tip.Sha;

            repo.Tags.Add("1.3.4", tipSha);

            AddACommit(local);
            repo.Head.Tip.Sha.Should().NotBeEquivalentTo(tipSha);

            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Tag, tag);
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : local,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeFalse();
            resp.RunnableState.Succeeded.Should().BeTrue();
            repo.Head.Tip.Sha.Should().BeEquivalentTo(tipSha);
            repo.Head.FriendlyName.Should().BeEquivalentTo(GitPatcherRun.RunnerBranch);
        }
 public async Task GetRepoTargetCalled(
     IGitRepository repo,
     GitPatcherVersioning patcherVersioning,
     CancellationToken cancel,
     ResetToTarget sut)
 {
     sut.Reset(repo, patcherVersioning, cancel);
     sut.GetRepoTarget.Received(1).Get(repo, patcherVersioning);
 }
 public void FailIfNotValidSha(
     [Frozen] IGitRepository repo,
     ICommit commit,
     RepoTarget targets,
     GitPatcherVersioning patcherVersioning,
     CancellationToken cancel,
     RetrieveCommit sut)
 {
     repo.TryGetCommit(default !, out _).ReturnsForAnyArgs(x =>
 public async Task CheckoutPassedToRunnerBranchCheckout(
     IGitRepository repo,
     GitPatcherVersioning patcherVersioning,
     CancellationToken cancel,
     ResetToTarget sut)
 {
     sut.Reset(repo, patcherVersioning, cancel);
     sut.CheckoutRunnerBranch.Received(1).Checkout(repo);
 }
 public void PassesShaToTryGetCommit(
     [Frozen] IGitRepository repo,
     RepoTarget targets,
     GitPatcherVersioning patcherVersioning,
     CancellationToken cancel,
     RetrieveCommit sut)
 {
     sut.TryGet(repo, targets, patcherVersioning, cancel);
     repo.Received(1).TryGetCommit(targets.TargetSha, out Arg.Any <bool>());
 }
Beispiel #13
0
        public GetResponse <RepoTarget> Get(
            IGitRepository repo,
            GitPatcherVersioning patcherVersioning)
        {
            string?targetSha;
            string?target;

            switch (patcherVersioning.Versioning)
            {
            case PatcherVersioningEnum.Tag:
                if (string.IsNullOrWhiteSpace(patcherVersioning.Target))
                {
                    return(GetResponse <RepoTarget> .Fail("No tag selected"));
                }
                repo.Fetch();
                if (!repo.TryGetTagSha(patcherVersioning.Target, out targetSha))
                {
                    return(GetResponse <RepoTarget> .Fail("Could not locate tag"));
                }
                target = patcherVersioning.Target;
                break;

            case PatcherVersioningEnum.Commit:
                targetSha = patcherVersioning.Target;
                if (string.IsNullOrWhiteSpace(targetSha))
                {
                    return(GetResponse <RepoTarget> .Fail("Could not locate commit"));
                }
                target = patcherVersioning.Target;
                break;

            case PatcherVersioningEnum.Branch:
                if (string.IsNullOrWhiteSpace(patcherVersioning.Target))
                {
                    return(GetResponse <RepoTarget> .Fail($"Target branch had no name."));
                }
                repo.Fetch();
                if (!repo.TryGetBranch(patcherVersioning.Target, out var targetBranch))
                {
                    return(GetResponse <RepoTarget> .Fail($"Could not locate branch: {patcherVersioning.Target}"));
                }
                targetSha = targetBranch.Tip.Sha;
                target    = patcherVersioning.Target;
                break;

            default:
                throw new NotImplementedException();
            }
            return(GetResponse <RepoTarget> .Succeed(
                       new RepoTarget(targetSha, target)));
        }
Beispiel #14
0
        public async Task UnknownSha()
        {
            using var repoPath = GetRepository(out var remote, out var local);
            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Commit, "46c207318c1531de7dc2f8e8c2a91aced183bc30");
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : local,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeTrue();
            resp.RunnableState.Succeeded.Should().BeFalse();
            resp.RunnableState.Reason.Should().Contain("Could not locate commit with given sha");
        }
        public void BranchVersioningWithoutAutoReturnsCommit(
            bool autoTag,
            string tag,
            string commit,
            string branch)
        {
            var ret = GitPatcherVersioning.Factory(
                PatcherVersioningEnum.Branch,
                tag,
                commit,
                branch,
                autoTag: autoTag,
                autoBranch: false);

            ret.Versioning.Should().Be(PatcherVersioningEnum.Commit);
            ret.Target.Should().Be(commit);
        }
        public void BranchVersioningWithAutoForwardsBranch(
            bool autoTag,
            string tag,
            string commit,
            string branch)
        {
            var ret = GitPatcherVersioning.Factory(
                PatcherVersioningEnum.Branch,
                tag,
                commit,
                branch,
                autoTag: autoTag,
                autoBranch: true);

            ret.Versioning.Should().Be(PatcherVersioningEnum.Branch);
            ret.Target.Should().Be(branch);
        }
        public void TagVersioningWithAutoForwardsTag(
            bool autoBranch,
            string tag,
            string commit,
            string branch)
        {
            var ret = GitPatcherVersioning.Factory(
                PatcherVersioningEnum.Tag,
                tag,
                commit,
                branch,
                autoTag: true,
                autoBranch: autoBranch);

            ret.Versioning.Should().Be(PatcherVersioningEnum.Tag);
            ret.Target.Should().Be(tag);
        }
Beispiel #18
0
        public async Task MalformedSha()
        {
            using var repoPath = GetRepository(out var remote, out var local);
            var versioning = new GitPatcherVersioning(PatcherVersioningEnum.Commit, "derp");
            var resp       = await GitPatcherRun.CheckoutRunnerRepository(
                proj : ProjPath,
                localRepoDir : local,
                patcherVersioning : versioning,
                nugetVersioning : TypicalNugetVersioning(),
                logger : null,
                cancel : CancellationToken.None,
                compile : false);

            resp.IsHaltingError.Should().BeTrue();
            resp.RunnableState.Succeeded.Should().BeFalse();
            resp.RunnableState.Reason.Should().Contain("Malformed sha string");
        }
        public GitPatcherTargetingVm(
            ILockToCurrentVersioning lockToCurrentVersioning,
            IDriverRepositoryPreparationFollower driverRepositoryPreparation)
        {
            var targetOriginBranchName = this.WhenAnyValue(x => x.TargetBranchName)
                                         .Select(x => $"origin/{x}")
                                         .Replay(1).RefCount();

            // Set latest checkboxes to drive user input
            driverRepositoryPreparation.DriverInfo
            .FlowSwitch(this.WhenAnyValue(x => x.BranchFollowMain))
            .Throttle(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
            .Subscribe(state =>
            {
                if (state.RunnableState.Succeeded)
                {
                    this.TargetBranchName = state.Item.MasterBranchName;
                }
            })
            .DisposeWith(this);

            Observable.CombineLatest(
                driverRepositoryPreparation.DriverInfo,
                targetOriginBranchName,
                (Driver, TargetBranch) => (Driver, TargetBranch))
            .FlowSwitch(
                Observable.CombineLatest(
                    this.WhenAnyValue(x => x.BranchAutoUpdate),
                    this.WhenAnyValue(x => x.PatcherVersioning),
                    (autoBranch, versioning) => autoBranch && versioning == PatcherVersioningEnum.Branch))
            .Throttle(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                if (x.Driver.RunnableState.Succeeded &&
                    x.Driver.Item.BranchShas.TryGetValue(x.TargetBranch, out var sha))
                {
                    this.TargetCommit = sha;
                }
            })
            .DisposeWith(this);

            driverRepositoryPreparation.DriverInfo
            .Select(x =>
                    x.RunnableState.Failed ? default : x.Item.Tags.OrderByDescending(x => x.Index).FirstOrDefault())
            .FlowSwitch(
                Observable.CombineLatest(
                    this.WhenAnyValue(x => x.TagAutoUpdate),
                    lockToCurrentVersioning.WhenAnyValue(x => x.Lock),
                    this.WhenAnyValue(x => x.PatcherVersioning),
                    (autoTag, locked, versioning) => !locked && autoTag && versioning == PatcherVersioningEnum.Tag))
            .Throttle(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                this.TargetTag    = x?.Name ?? string.Empty;
                this.TargetCommit = x?.Sha ?? string.Empty;
            })
            .DisposeWith(this);

            var targetBranchSha = Observable.CombineLatest(
                driverRepositoryPreparation.DriverInfo
                .Select(x => x.RunnableState.Failed ? default : x.Item.BranchShas),
                targetOriginBranchName,
                (dict, branch) => dict?.GetOrDefault(branch))
                                  .Replay(1)
                                  .RefCount();

            var targetTag = Observable.CombineLatest(
                driverRepositoryPreparation.DriverInfo
                .Select(x => x.RunnableState.Failed ? default : x.Item.Tags),
                this.WhenAnyValue(x => x.TargetTag),
                (tags, tag) => tags?
                .Where(tagItem => tagItem.Name == tag)
                .FirstOrDefault())
                            .Replay(1)
                            .RefCount();

            // Set up empty target autofill
            // Usually for initial bootstrapping
            Observable.CombineLatest(
                targetBranchSha,
                this.WhenAnyValue(x => x.TargetCommit),
                (targetBranchSha, targetCommit) => (targetBranchSha, targetCommit))
            .Throttle(TimeSpan.FromMilliseconds(200), RxApp.MainThreadScheduler)
            .Where(x => x.targetBranchSha != null && TargetCommit.IsNullOrWhitespace())
            .Subscribe(x => { this.TargetCommit = x.targetBranchSha ?? string.Empty; })
            .DisposeWith(this);
            Observable.CombineLatest(
                targetTag,
                this.WhenAnyValue(x => x.TargetCommit),
                (targetTagSha, targetCommit) => (targetTagSha, targetCommit))
            .Throttle(TimeSpan.FromMilliseconds(200), RxApp.MainThreadScheduler)
            .Where(x => x.targetTagSha != null && TargetCommit.IsNullOrWhitespace())
            .Subscribe(x => { this.TargetCommit = x.targetTagSha?.Sha ?? string.Empty; })
            .DisposeWith(this);

            // Set up update available systems
            UpdateToBranchCommand = NoggogCommand.CreateFromObject(
                objectSource: Observable.CombineLatest(
                    targetBranchSha,
                    this.WhenAnyValue(x => x.TargetCommit),
                    (branch, target) => (BranchSha: branch, Current: target)),
                canExecute: o => o.BranchSha != null && o.BranchSha != o.Current,
                extraCanExecute: this.WhenAnyValue(x => x.PatcherVersioning)
                .Select(vers => vers == PatcherVersioningEnum.Branch),
                execute: o => { this.TargetCommit = o.BranchSha !; },
                this);

            UpdateToTagCommand = NoggogCommand.CreateFromObject(
                objectSource: Observable.CombineLatest(
                    targetTag,
                    Observable.CombineLatest(
                        this.WhenAnyValue(x => x.TargetCommit),
                        this.WhenAnyValue(x => x.TargetTag),
                        (TargetSha, TargetTag) => (TargetSha, TargetTag)),
                    (tag, target) => (TagSha: tag?.Sha, Tag: tag?.Name, Current: target)),
                canExecute: o => (o.TagSha != null && o.Tag != null) &&
                (o.TagSha != o.Current.TargetSha || o.Tag != o.Current.TargetTag),
                extraCanExecute: this.WhenAnyValue(x => x.PatcherVersioning)
                .Select(vers => vers == PatcherVersioningEnum.Tag),
                execute: o =>
            {
                this.TargetTag    = o.Tag !;
                this.TargetCommit = o.TagSha !;
            },
                this);

            ActivePatcherVersion = Observable.CombineLatest(
                this.WhenAnyValue(x => x.PatcherVersioning),
                this.WhenAnyValue(x => x.TargetTag),
                this.WhenAnyValue(x => x.TargetCommit),
                targetOriginBranchName,
                Observable.CombineLatest(
                    this.WhenAnyValue(x => x.TagAutoUpdate),
                    lockToCurrentVersioning.WhenAnyValue(x => x.Lock),
                    (auto, locked) => !locked && auto),
                Observable.CombineLatest(
                    this.WhenAnyValue(x => x.BranchAutoUpdate),
                    lockToCurrentVersioning.WhenAnyValue(x => x.Lock),
                    (auto, locked) => !locked && auto),
                (versioning, tag, commit, branch, tagAuto, branchAuto) =>
            {
                return(GitPatcherVersioning.Factory(
                           versioning: versioning,
                           tag: tag,
                           commit: commit,
                           branch: branch,
                           autoTag: tagAuto,
                           autoBranch: branchAuto));
            })
                                   .DistinctUntilChanged()
                                   .Replay(1)
                                   .RefCount();
        }