Skip to content

Commit

Permalink
Improve stack cleanup and delete (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
geofflamrock authored Nov 22, 2024
1 parent aaa6570 commit f47b0bc
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 19 deletions.
12 changes: 6 additions & 6 deletions src/Stack.Tests/Commands/Stack/DeleteStackCommandHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public async Task WhenNoInputsAreProvided_AsksForName_AndConfirmation_AndDeletes
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Select(Questions.SelectStack, Arg.Any<string[]>()).Returns("Stack1");
inputProvider.Confirm(Questions.ConfirmDeleteStack).Returns(true);
inputProvider.Confirm(Questions.ConfirmDeleteStack("Stack1")).Returns(true);

// Act
var response = await handler.Handle(DeleteStackCommandInputs.Empty);
Expand Down Expand Up @@ -78,7 +78,7 @@ public async Task WhenConfirmationIsFalse_DoesNotDeleteStack()
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Select(Questions.SelectStack, Arg.Any<string[]>()).Returns("Stack1");
inputProvider.Confirm(Questions.ConfirmDeleteStack).Returns(false);
inputProvider.Confirm(Questions.ConfirmDeleteStack("Stack1")).Returns(false);

// Act
var response = await handler.Handle(DeleteStackCommandInputs.Empty);
Expand Down Expand Up @@ -118,7 +118,7 @@ public async Task WhenNameIsProvided_AsksForConfirmation_AndDeletesStack()
.WhenForAnyArgs(s => s.Save(Arg.Any<List<Config.Stack>>()))
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Confirm(Questions.ConfirmDeleteStack).Returns(true);
inputProvider.Confirm(Questions.ConfirmDeleteStack("Stack1")).Returns(true);

// Act
var response = await handler.Handle(new DeleteStackCommandInputs("Stack1", false));
Expand Down Expand Up @@ -171,7 +171,7 @@ public async Task WhenForceIsProvided_DoesNotAskForConfirmation_AndDeletesStack(
new("Stack2", remoteUri, "branch-2", [])
});

inputProvider.DidNotReceive().Confirm(Questions.ConfirmDeleteStack);
inputProvider.DidNotReceive().Confirm(Questions.ConfirmDeleteStack("Stack1"));
}

[Fact]
Expand Down Expand Up @@ -239,7 +239,7 @@ public async Task WhenStackDoesNotExist_Throws()
.WhenForAnyArgs(s => s.Save(Arg.Any<List<Config.Stack>>()))
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Confirm(Questions.ConfirmDeleteStack).Returns(true);
inputProvider.Confirm(Questions.ConfirmDeleteStack("Stack1")).Returns(true);

// Act and assert
await handler
Expand Down Expand Up @@ -278,7 +278,7 @@ public async Task WhenThereAreLocalBranchesThatAreNotInTheRemote_AsksToCleanup_A
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Select(Questions.SelectStack, Arg.Any<string[]>()).Returns("Stack1");
inputProvider.Confirm(Questions.ConfirmDeleteStack).Returns(true);
inputProvider.Confirm(Questions.ConfirmDeleteStack("Stack1")).Returns(true);
inputProvider.Confirm(Questions.ConfirmDeleteBranches).Returns(true);

// Act
Expand Down
5 changes: 2 additions & 3 deletions src/Stack/Commands/Helpers/Questions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Spectre.Console;
using Stack.Config;
using Stack.Infrastructure;

namespace Stack.Commands.Helpers;

public static class Questions
{
public const string SelectStack = "Select stack:";
public const string ConfirmDeleteStack = "Are you sure you want to delete this stack?";
public static string ConfirmDeleteStack(string name) => $"Are you sure you want to delete stack {name.Stack()}?";
public const string ConfirmDeleteBranches = "Are you sure you want to delete these local branches?";
}
2 changes: 1 addition & 1 deletion src/Stack/Commands/Stack/CleanupStackCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static string[] GetBranchesNeedingCleanup(Config.Stack stack, IGitOperati

public static void OutputBranchesNeedingCleanup(IOutputProvider outputProvider, string[] branches)
{
outputProvider.Information("The following branches exist locally but not on the remote or pull request associated with the branch is no longer open:");
outputProvider.Information("The following branches exist locally but are either not in the remote repository or the pull request associated with the branch is no longer open:");

foreach (var branch in branches)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Stack/Commands/Stack/DeleteStackCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public override async Task<int> ExecuteAsync(CommandContext context, DeleteStack
var response = await handler.Handle(new DeleteStackCommandInputs(settings.Name, settings.Force));

if (response.DeletedStackName is not null)
console.MarkupLine($"Stack {response.DeletedStackName.Branch()} deleted");
console.MarkupLine($"Stack {response.DeletedStackName.Stack()} deleted");

return 0;
}
Expand Down Expand Up @@ -76,7 +76,7 @@ public async Task<DeleteStackCommandResponse> Handle(DeleteStackCommandInputs in
throw new InvalidOperationException("Stack not found.");
}

if (inputs.Force || inputProvider.Confirm(Questions.ConfirmDeleteStack))
if (inputs.Force || inputProvider.Confirm(Questions.ConfirmDeleteStack(stack.Name)))
{
var branchesNeedingCleanup = CleanupStackCommandHandler.GetBranchesNeedingCleanup(stack, gitOperations, gitHubOperations);

Expand Down
30 changes: 23 additions & 7 deletions src/Stack/Commands/Stack/StackStatusCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ string BuildBranchName(string branch, string? parentBranch, bool isSourceBranchF
var branchNameBuilder = new StringBuilder();

var color = branchDetail?.Status.ExistsInRemote == false ? "grey" : isSourceBranchForStack ? "grey" : branch.Equals(currentBranch, StringComparison.OrdinalIgnoreCase) ? "blue" : null;
Decoration? decoration = branchDetail?.Status.ExistsInRemote == false ? Decoration.Strikethrough : null;
Decoration? decoration = branchDetail?.Status.ExistsInRemote == false || branchDetail?.Status.ExistsLocally == false ? Decoration.Strikethrough : null;

if (color is not null && decoration is not null)
{
Expand Down Expand Up @@ -117,23 +117,39 @@ string BuildBranchName(string branch, string? parentBranch, bool isSourceBranchF

bool BranchCouldBeCleanedUp(BranchDetail branchDetail)
{
return branchDetail.Status.ExistsLocally && !branchDetail.Status.ExistsInRemote ||
branchDetail.PullRequest is not null && branchDetail.PullRequest.State != GitHubPullRequestStates.Open;
return branchDetail.Status.ExistsLocally &&
(!branchDetail.Status.ExistsInRemote ||
branchDetail.PullRequest is not null && branchDetail.PullRequest.State != GitHubPullRequestStates.Open);
}

if (status.Branches.Values.All(branch => BranchCouldBeCleanedUp(branch)))
{
console.WriteLine();
console.MarkupLine("All branches exist locally but not in the remote repository or the pull request associated with the branch is no longer open. This stack might be able to be deleted.");
console.MarkupLine("All branches exist locally but are either not in the remote repository or the pull request associated with the branch is no longer open. This stack might be able to be deleted.");
console.WriteLine();
console.MarkupLine($"Run [purple]stack delete --name \"{stack.Name}\"[/] to delete the stack if it's no longer needed.");
console.MarkupLine($"Run [aqua]stack delete --name \"{stack.Name}\"[/] to delete the stack if it's no longer needed.");
}
else if (status.Branches.Values.Any(branch => BranchCouldBeCleanedUp(branch)))
{
console.WriteLine();
console.MarkupLine("Some branches exist locally but not in the remote repository or the pull request associated with the branch is no longer open.");
console.MarkupLine("Some branches exist locally but are either not in the remote repository or the pull request associated with the branch is no longer open.");
console.WriteLine();
console.MarkupLine($"Run [purple]stack cleanup --name \"{stack.Name}\"[/] to clean up local branches.");
console.MarkupLine($"Run [aqua]stack cleanup --name \"{stack.Name}\"[/] to clean up local branches.");
}
else if (status.Branches.Values.All(branch => !branch.Status.ExistsLocally))
{
console.WriteLine();
console.MarkupLine("No branches exist locally. This stack might be able to be deleted.");
console.WriteLine();
console.MarkupLine($"Run [aqua]stack delete --name \"{stack.Name}\"[/] to delete the stack.");
}

if (status.Branches.Values.Any(branch => branch.Status.ExistsInRemote && branch.Status.ExistsLocally && branch.Status.Behind > 0))
{
console.WriteLine();
console.MarkupLine("There are changes in source branches that have not been applied to the stack.");
console.WriteLine();
console.MarkupLine($"Run [aqua]stack update --name \"{stack.Name}\"[/] to update the stack.");
}
}

Expand Down

0 comments on commit f47b0bc

Please sign in to comment.