diff --git a/README.md b/README.md index 722b659b..614f2f5b 100644 --- a/README.md +++ b/README.md @@ -150,11 +150,11 @@ To do this: - For each branch you'll be asked for the title of the pull request. - The pull request will then be created, targeting the previous branch in the stack. -When all the pull requests have been created you'll be asked for a pull request stack description if there is more than 1 pull request in the stack. This will be added to the top of the description of each pull request along with a set of links to all pull requests in the stack. For an example of this look at https://github.com/geofflamrock/stack/pull/32. +When all the pull requests have been created set of links to all pull requests in the stack will be put into the body of each pull request. This is optional and is controlled by the presence of the `` comment in the body of the pull request. To opt-out just remove the comment. You can then open each pull request if the stack if you want to view them. -`stack pr create` can be run multiple times, if there are new branches in the stack that don't have an associated pull request these will be created and the description updated on each pull request. +`stack pr create` can be run multiple times, if there are new branches in the stack that don't have an associated pull request these will be created and the list updated on each pull request. ## Commands @@ -423,21 +423,6 @@ OPTIONS: -s, --stack The name of the stack to open PRs for ``` -#### `stack pr description` - -Sets the pull request description for the stack and applies it all pull requests. - -```shell -USAGE: - stack pr description [OPTIONS] - -OPTIONS: - -h, --help Prints help information - --verbose Show verbose output - --working-dir The path to the directory containing the git repository. Defaults to the current directory - -s, --stack The name of the stack to open PRs for -``` - ### Advanced commands #### `stack config open` diff --git a/src/Stack.Tests/Commands/PullRequests/CreatePullRequestsCommandHandlerTests.cs b/src/Stack.Tests/Commands/PullRequests/CreatePullRequestsCommandHandlerTests.cs index 56911eba..dd37a81e 100644 --- a/src/Stack.Tests/Commands/PullRequests/CreatePullRequestsCommandHandlerTests.cs +++ b/src/Stack.Tests/Commands/PullRequests/CreatePullRequestsCommandHandlerTests.cs @@ -53,15 +53,12 @@ public async Task WhenNoPullRequestsExistForAStackWithMultipleBranches_CreatesPu .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd}"; @@ -82,7 +79,7 @@ private static EquivalencyAssertionOptions } [Fact] - public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPullRequestHasTheCorrectStackDescription() + public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPullRequestHasTheCorrectPullRequestList() { // Arrange var sourceBranch = Some.BranchName(); @@ -120,23 +117,20 @@ public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPull .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert - var expectedStackDescription = $@"{StackConstants.StackMarkerStart} -A custom description - + var expectedPullRequestList = $@"{StackConstants.StackMarkerStart} {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd}"; - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedStackDescription)); + gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPullRequestList)); } [Fact] - public async Task WhenAPullRequestExistForABranch_AndNoneForAnotherBranch_CreatesPullRequestForTheCorrectBranchAndSetsDescription() + public async Task WhenAPullRequestExistForABranch_AndNoneForAnotherBranch_CreatesPullRequestForTheCorrectBranchAndSetsPullRequestList() { // Arrange var sourceBranch = Some.BranchName(); @@ -176,20 +170,17 @@ public async Task WhenAPullRequestExistForABranch_AndNoneForAnotherBranch_Create .Returns([new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert var pullRequestUrls = gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}").ToArray(); - var expectedStackDescription = $@"{StackConstants.StackMarkerStart} -A custom description - + var expectedPullRequestList = $@"{StackConstants.StackMarkerStart} {string.Join(Environment.NewLine, pullRequestUrls)} {StackConstants.StackMarkerEnd}"; - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedStackDescription)); + gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPullRequestList)); } [Fact] @@ -231,15 +222,12 @@ public async Task WhenStackNameIsProvided_PullRequestsAreCreatedForThatStack() .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(new CreatePullRequestsCommandInputs("Stack1")); // Assert var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd}"; @@ -286,15 +274,12 @@ public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_PullRequestsAreC .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd}"; @@ -393,15 +378,12 @@ public async Task WhenAPullRequestExistForABranch_AndHasBeenMerged_AndNoneForAno .Returns([new PullRequestCreateAction(branch2, sourceBranch)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd}"; @@ -456,15 +438,12 @@ public async Task WhenAPullRequestTemplateExistsInTheRepo_ItIsUsedAsTheBodyOfANe .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); // Act await handler.Handle(CreatePullRequestsCommandInputs.Empty); // Assert var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - {string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} {StackConstants.StackMarkerEnd} This is the PR template"; @@ -640,64 +619,4 @@ public async Task WhenOnlySelectingSomeBranchesToCreatePullRequestsFor_OnlyThose gitHubClient.PullRequests.Should().BeEquivalentTo(expectedPullRequests, ExcludeUnimportantPullRequestProperties); } - - [Fact] - public async Task WhenPullRequestDescriptionExistsForStack_DoesNotAskForItAgain() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder().Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2)) - .WithPullRequestDescription("A custom description")) - .WithStack(stack => stack - .WithName("Stack2") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch)) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var fileOperations = new FileOperations(); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new CreatePullRequestsCommandHandler(inputProvider, logger, gitClient, gitHubClient, fileOperations, stackConfig); - - inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); - inputProvider - .MultiSelect(Questions.SelectPullRequestsToCreate, Arg.Any(), true, Arg.Any>()) - .Returns([new PullRequestCreateAction(branch1, sourceBranch), new PullRequestCreateAction(branch2, branch1)]); - inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true); - inputProvider.Text(Questions.PullRequestTitle).Returns("PR Title"); - - // Act - await handler.Handle(CreatePullRequestsCommandInputs.Empty); - - // Assert - var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - -{string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} -{StackConstants.StackMarkerEnd}"; - - var expectedPullRequests = new Dictionary - { - [branch1] = new GitHubPullRequest(1, "PR Title", expectedPrBody, GitHubPullRequestStates.Open, Some.HttpsUri(), false, branch1), - [branch2] = new GitHubPullRequest(2, "PR Title", expectedPrBody, GitHubPullRequestStates.Open, Some.HttpsUri(), false, branch2) - }; - - gitHubClient.PullRequests.Should().BeEquivalentTo(expectedPullRequests, ExcludeUnimportantPullRequestProperties); - inputProvider.DidNotReceive().Text(Questions.PullRequestStackDescription, Arg.Any()); - } } diff --git a/src/Stack.Tests/Commands/PullRequests/SetPullRequestDescriptionCommandHandlerTests.cs b/src/Stack.Tests/Commands/PullRequests/SetPullRequestDescriptionCommandHandlerTests.cs deleted file mode 100644 index 41067df1..00000000 --- a/src/Stack.Tests/Commands/PullRequests/SetPullRequestDescriptionCommandHandlerTests.cs +++ /dev/null @@ -1,250 +0,0 @@ -using FluentAssertions; -using NSubstitute; -using Stack.Commands; -using Stack.Commands.Helpers; -using Stack.Config; -using Stack.Git; -using Stack.Infrastructure; -using Stack.Tests.Helpers; -using Xunit.Abstractions; - -namespace Stack.Tests.Commands.PullRequests; - -public class SetPullRequestDescriptionCommandHandlerTests(ITestOutputHelper testOutputHelper) -{ - [Fact] - public async Task WhenPullRequestsExistInAStack_TheNewDescriptionIsAppliedCorrectlyAlongWithTheListOfPrs() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder() - .WithPullRequest(branch1, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .WithPullRequest(branch2, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2))) - .WithStack(stack => stack - .WithName("Stack2") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch)) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new SetPullRequestDescriptionCommandHandler(inputProvider, logger, gitClient, gitHubClient, stackConfig); - - - inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); - - // Act - await handler.Handle(SetPullRequestDescriptionCommandInputs.Empty); - - // Assert - var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - -{string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} -{StackConstants.StackMarkerEnd}"; - - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPrBody)); - } - - [Fact] - public async Task WhenPullRequestsOnlyExistForSomeBranchesInAStack_TheNewDescriptionIsAppliedCorrectlyAlongWithTheListOfPrs() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder() - .WithPullRequest(branch1, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2))) - .WithStack(stack => stack - .WithName("Stack2") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch)) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new SetPullRequestDescriptionCommandHandler(inputProvider, logger, gitClient, gitHubClient, stackConfig); - - - inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); - - // Act - await handler.Handle(SetPullRequestDescriptionCommandInputs.Empty); - - // Assert - var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - -{string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} -{StackConstants.StackMarkerEnd}"; - - gitHubClient.PullRequests.Should().ContainSingle(); - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPrBody)); - } - - [Fact] - public async Task WhenStackNameIsProvided_ButTheStackDoesNotExist_Throws() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder().Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2))) - .WithStack(stack => stack - .WithName("Stack2") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch)) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new SetPullRequestDescriptionCommandHandler(inputProvider, logger, gitClient, gitHubClient, stackConfig); - - - // Act and assert - var invalidStackName = Some.Name(); - await handler.Invoking(h => h.Handle(new SetPullRequestDescriptionCommandInputs(invalidStackName))) - .Should() - .ThrowAsync() - .WithMessage($"Stack '{invalidStackName}' not found."); - } - - [Fact] - public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_TheNewDescriptionIsAppliedCorrectlyAlongWithTheListOfPrs() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder() - .WithPullRequest(branch1, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .WithPullRequest(branch2, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2))) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new SetPullRequestDescriptionCommandHandler(inputProvider, logger, gitClient, gitHubClient, stackConfig); - - - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); - - // Act - await handler.Handle(SetPullRequestDescriptionCommandInputs.Empty); - - // Assert - var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - -{string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} -{StackConstants.StackMarkerEnd}"; - - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPrBody)); - inputProvider.DidNotReceive().Select(Questions.SelectStack, Arg.Any()); - } - - [Fact] - public async Task WhenStackNameIsProvided_DoesNotAskForStackName_TheNewDescriptionIsAppliedCorrectlyAlongWithTheListOfPrs() - { - // Arrange - var sourceBranch = Some.BranchName(); - var branch1 = Some.BranchName(); - var branch2 = Some.BranchName(); - using var repo = new TestGitRepositoryBuilder() - .WithBranch(sourceBranch, true) - .WithBranch(branch1, true) - .WithBranch(branch2, true) - .Build(); - - var gitHubClient = new TestGitHubRepositoryBuilder() - .WithPullRequest(branch1, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .WithPullRequest(branch2, pr => pr.WithBody($"{StackConstants.StackMarkerStart} The current description {StackConstants.StackMarkerEnd}")) - .Build(); - var stackConfig = new TestStackConfigBuilder() - .WithStack(stack => stack - .WithName("Stack1") - .WithRemoteUri(repo.RemoteUri) - .WithSourceBranch(sourceBranch) - .WithBranch(branch => branch.WithName(branch1)) - .WithBranch(branch => branch.WithName(branch2))) - .Build(); - var inputProvider = Substitute.For(); - var logger = new TestLogger(testOutputHelper); - var gitClient = new GitClient(logger, repo.GitClientSettings); - var handler = new SetPullRequestDescriptionCommandHandler(inputProvider, logger, gitClient, gitHubClient, stackConfig); - - - inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any()).Returns("A custom description"); - - // Act - await handler.Handle(new SetPullRequestDescriptionCommandInputs("Stack1")); - - // Assert - var expectedPrBody = $@"{StackConstants.StackMarkerStart} -A custom description - -{string.Join(Environment.NewLine, gitHubClient.PullRequests.Values.Select(pr => $"- {pr.Url}"))} -{StackConstants.StackMarkerEnd}"; - - gitHubClient.PullRequests.Should().AllSatisfy(pr => pr.Value.Body.Should().Be(expectedPrBody)); - inputProvider.DidNotReceive().Select(Questions.SelectStack, Arg.Any()); - } -} diff --git a/src/Stack.Tests/Config/FileStackConfigTests.cs b/src/Stack.Tests/Config/FileStackConfigTests.cs index 63c22200..e22c3ade 100644 --- a/src/Stack.Tests/Config/FileStackConfigTests.cs +++ b/src/Stack.Tests/Config/FileStackConfigTests.cs @@ -39,7 +39,6 @@ public void Load_WhenConfigFileIsInV1Format_LoadsCorrectly() var sourceBranch = Some.BranchName(); var branch1 = Some.BranchName(); var branch2 = Some.BranchName(); - var prDescription = "Test PR description"; // Create a V1 format config file directly as JSON var v1Json = $@"[ @@ -47,8 +46,7 @@ public void Load_WhenConfigFileIsInV1Format_LoadsCorrectly() ""Name"": ""{stackName}"", ""RemoteUri"": ""{remoteUri}"", ""SourceBranch"": ""{sourceBranch}"", - ""Branches"": [""{branch1}"", ""{branch2}""], - ""PullRequestDescription"": ""{prDescription}"" + ""Branches"": [""{branch1}"", ""{branch2}""] }} ]"; File.WriteAllText(configPath, v1Json); @@ -64,7 +62,6 @@ public void Load_WhenConfigFileIsInV1Format_LoadsCorrectly() new(branch2, []) ]) ]); - expectedStack.SetPullRequestDescription(prDescription); // Act var stackData = fileStackConfig.Load(); @@ -87,7 +84,6 @@ public void Load_WhenConfigFileIsInV2Format_LoadsCorrectly() var branch1 = Some.BranchName(); var branch2 = Some.BranchName(); var branch3 = Some.BranchName(); - var prDescription = "Test PR description"; // Create a V2 format config file with multiple trees directly as JSON var v2Json = $@"{{ @@ -111,8 +107,7 @@ public void Load_WhenConfigFileIsInV2Format_LoadsCorrectly() ""Name"": ""{branch3}"", ""Children"": [] }} - ], - ""PullRequestDescription"": ""{prDescription}"" + ] }} ] }}"; @@ -128,7 +123,6 @@ public void Load_WhenConfigFileIsInV2Format_LoadsCorrectly() new(branch1, [new(branch2, [])]), new(branch3, []) ]); - expectedStack.SetPullRequestDescription(prDescription); // Act var stackData = fileStackConfig.Load(); @@ -148,7 +142,6 @@ public void Save_WhenConfigFileIsInV1Format_AndAllStacksHaveASingleTree_SavesCor var sourceBranch = Some.BranchName(); var branch1 = Some.BranchName(); var branch2 = Some.BranchName(); - var prDescription = "Test PR description"; // Create an empty config file Directory.CreateDirectory(Path.GetDirectoryName(configPath)!); @@ -165,7 +158,6 @@ public void Save_WhenConfigFileIsInV1Format_AndAllStacksHaveASingleTree_SavesCor new(branch2, []) ]) ]); - stack.SetPullRequestDescription(prDescription); // Act var fileStackConfig = new FileStackConfig(tempDirectory.DirectoryPath); @@ -183,8 +175,7 @@ public void Save_WhenConfigFileIsInV1Format_AndAllStacksHaveASingleTree_SavesCor ""Branches"": [ ""{branch1}"", ""{branch2}"" - ], - ""PullRequestDescription"": ""{prDescription}"" + ] }} ]"; @@ -208,7 +199,6 @@ public void Save_WhenConfigFileIsInV1Format_AndStackIsChangedToHaveTreeStructure var branch1 = Some.BranchName(); var branch2 = Some.BranchName(); var branch3 = Some.BranchName(); - var prDescription = "Test PR description"; // Create an empty config file in v1 format Directory.CreateDirectory(Path.GetDirectoryName(configPath)!); @@ -217,8 +207,7 @@ public void Save_WhenConfigFileIsInV1Format_AndStackIsChangedToHaveTreeStructure ""Name"": ""{stackName}"", ""RemoteUri"": ""{remoteUri}"", ""SourceBranch"": ""{sourceBranch}"", - ""Branches"": [""{branch1}"", ""{branch2}""], - ""PullRequestDescription"": ""{prDescription}"" + ""Branches"": [""{branch1}"", ""{branch2}""] }} ]"; File.WriteAllText(configPath, v1Json); @@ -231,7 +220,6 @@ public void Save_WhenConfigFileIsInV1Format_AndStackIsChangedToHaveTreeStructure new(branch1, [new(branch2, [])]), new(branch3, []) ]); - stack.SetPullRequestDescription(prDescription); var fileStackConfig = new FileStackConfig(tempDirectory.DirectoryPath); @@ -261,8 +249,7 @@ public void Save_WhenConfigFileIsInV1Format_AndStackIsChangedToHaveTreeStructure ""Name"": ""{branch3}"", ""Children"": [] }} - ], - ""PullRequestDescription"": ""{prDescription}"" + ] }} ] }}"; diff --git a/src/Stack.Tests/Helpers/TestStackConfigBuilder.cs b/src/Stack.Tests/Helpers/TestStackConfigBuilder.cs index 4af17276..29c46f63 100644 --- a/src/Stack.Tests/Helpers/TestStackConfigBuilder.cs +++ b/src/Stack.Tests/Helpers/TestStackConfigBuilder.cs @@ -39,7 +39,6 @@ public class TestStackBuilder string? remoteUri; string? sourceBranch; List> branchBuilders = []; - string? pullRequestDescription; public TestStackBuilder WithName(string name) { @@ -65,12 +64,6 @@ public TestStackBuilder WithBranch(Action branchBuilder) return this; } - public TestStackBuilder WithPullRequestDescription(string pullRequestDescription) - { - this.pullRequestDescription = pullRequestDescription; - return this; - } - public Config.Stack Build() { var branches = branchBuilders @@ -84,11 +77,6 @@ public Config.Stack Build() var stack = new Config.Stack(name ?? Some.Name(), remoteUri ?? Some.HttpsUri().ToString(), sourceBranch ?? Some.BranchName(), branches); - if (pullRequestDescription is not null) - { - stack.SetPullRequestDescription(pullRequestDescription); - } - return stack; } } diff --git a/src/Stack/Commands/Helpers/Questions.cs b/src/Stack/Commands/Helpers/Questions.cs index 7f24c80a..8f8afee6 100644 --- a/src/Stack/Commands/Helpers/Questions.cs +++ b/src/Stack/Commands/Helpers/Questions.cs @@ -17,7 +17,6 @@ public static class Questions public const string SelectPullRequestsToCreate = "Select branches to create pull requests for:"; public const string ConfirmCreatePullRequests = "Are you sure you want to create pull requests for branches in this stack?"; public const string PullRequestTitle = "Title:"; - public const string PullRequestStackDescription = "Stack description for pull request:"; public const string OpenPullRequests = "Open new pull requests in a browser?"; public const string CreatePullRequestAsDraft = "Create pull request as draft?"; public const string ContinueOrAbortMerge = "Conflict(s) detected during merge. Please either resolve the conflicts, commit the result and select Continue to continue merging, or Abort."; diff --git a/src/Stack/Commands/Helpers/StackHelpers.cs b/src/Stack/Commands/Helpers/StackHelpers.cs index 79323c51..fde641b5 100644 --- a/src/Stack/Commands/Helpers/StackHelpers.cs +++ b/src/Stack/Commands/Helpers/StackHelpers.cs @@ -642,7 +642,7 @@ public static void CleanupBranches(IGitClient gitClient, ILogger logger, string[ } } - public static void UpdateStackDescriptionInPullRequests( + public static void UpdateStackPullRequestList( ILogger logger, IGitHubClient gitHubClient, Config.Stack stack, @@ -676,7 +676,7 @@ void AppendBranchPullRequestsToList(Branch branch, int indentLevel) // Edit each PR and add to the top of the description // the details of each PR in the stack - var prBodyMarkdown = $"{StackConstants.StackMarkerStart}{Environment.NewLine}{stack.PullRequestDescription}{Environment.NewLine}{Environment.NewLine}{prListBuilder}{StackConstants.StackMarkerEnd}"; + var prBodyMarkdown = $"{StackConstants.StackMarkerStart}{Environment.NewLine}{prListBuilder}{StackConstants.StackMarkerEnd}"; foreach (var pullRequest in pullRequestsInStack) { @@ -699,18 +699,6 @@ void AppendBranchPullRequestsToList(Branch branch, int indentLevel) } } - public static void UpdateStackPullRequestDescription(IInputProvider inputProvider, IStackConfig stackConfig, StackData stackData, Config.Stack stack) - { - var defaultStackDescription = stack.PullRequestDescription ?? $"This PR is part of a stack **{stack.Name}**:"; - var stackDescription = inputProvider.Text(Questions.PullRequestStackDescription, defaultStackDescription); - - if (stackDescription != stack.PullRequestDescription) - { - stack.SetPullRequestDescription(stackDescription); - stackConfig.Save(stackData); - } - } - static void MergeFromSourceBranch(string branch, string sourceBranchName, IGitClient gitClient, IInputProvider inputProvider, ILogger logger) { logger.Information($"Merging {sourceBranchName.Branch()} into {branch.Branch()}"); diff --git a/src/Stack/Commands/PullRequests/CreatePullRequestsCommand.cs b/src/Stack/Commands/PullRequests/CreatePullRequestsCommand.cs index 470c88ba..c30ff8ce 100644 --- a/src/Stack/Commands/PullRequests/CreatePullRequestsCommand.cs +++ b/src/Stack/Commands/PullRequests/CreatePullRequestsCommand.cs @@ -144,7 +144,7 @@ public override async Task Handle(CreatePullRequestsCommandInputs inputs) if (pullRequestsInStack.Count > 1) { - UpdatePullRequestStackDescriptions(inputProvider, logger, gitHubClient, stackConfig, stackData, stack, pullRequestsInStack); + StackHelpers.UpdateStackPullRequestList(logger, gitHubClient, stack, pullRequestsInStack); } if (inputProvider.Confirm(Questions.OpenPullRequests)) @@ -162,23 +162,6 @@ public override async Task Handle(CreatePullRequestsCommandInputs inputs) } } - private static void UpdatePullRequestStackDescriptions( - IInputProvider inputProvider, - ILogger logger, - IGitHubClient gitHubClient, - IStackConfig stackConfig, - StackData stacks, - Config.Stack stack, - List pullRequestsInStack) - { - if (stack.PullRequestDescription is null) - { - StackHelpers.UpdateStackPullRequestDescription(inputProvider, stackConfig, stacks, stack); - } - - StackHelpers.UpdateStackDescriptionInPullRequests(logger, gitHubClient, stack, pullRequestsInStack); - } - private static List CreatePullRequests( ILogger logger, IGitHubClient gitHubClient, diff --git a/src/Stack/Commands/PullRequests/PullRequestsCommand.cs b/src/Stack/Commands/PullRequests/PullRequestsCommand.cs index 83e33355..478bcb1c 100644 --- a/src/Stack/Commands/PullRequests/PullRequestsCommand.cs +++ b/src/Stack/Commands/PullRequests/PullRequestsCommand.cs @@ -6,6 +6,5 @@ public class PullRequestsCommand : GroupCommand { Add(new CreatePullRequestsCommand()); Add(new OpenPullRequestsCommand()); - Add(new SetPullRequestDescriptionCommand()); } } diff --git a/src/Stack/Commands/PullRequests/SetPullRequestDescriptionCommand.cs b/src/Stack/Commands/PullRequests/SetPullRequestDescriptionCommand.cs deleted file mode 100644 index 860dbe00..00000000 --- a/src/Stack/Commands/PullRequests/SetPullRequestDescriptionCommand.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.CommandLine; -using Stack.Commands.Helpers; -using Stack.Config; -using Stack.Git; -using Stack.Infrastructure; - -namespace Stack.Commands; - -public class SetPullRequestDescriptionCommand : Command -{ - public SetPullRequestDescriptionCommand() : base("description", "Set the pull request description for the stack and apply it to all pull requests.") - { - Add(CommonOptions.Stack); - } - - protected override async Task Execute(ParseResult parseResult, CancellationToken cancellationToken) - { - var handler = new SetPullRequestDescriptionCommandHandler( - InputProvider, - StdErrLogger, - new GitClient(StdErrLogger, new GitClientSettings(Verbose, WorkingDirectory)), - new GitHubClient(StdErrLogger, new GitHubClientSettings(Verbose, WorkingDirectory)), - new FileStackConfig()); - - await handler.Handle(new SetPullRequestDescriptionCommandInputs( - parseResult.GetValue(CommonOptions.Stack))); - } -} - -public record SetPullRequestDescriptionCommandInputs(string? Stack) -{ - public static SetPullRequestDescriptionCommandInputs Empty => new((string?)null); -} - -public class SetPullRequestDescriptionCommandHandler( - IInputProvider inputProvider, - ILogger logger, - IGitClient gitClient, - IGitHubClient gitHubClient, - IStackConfig stackConfig) - : CommandHandlerBase -{ - public override async Task Handle(SetPullRequestDescriptionCommandInputs inputs) - { - await Task.CompletedTask; - var stackData = stackConfig.Load(); - - var remoteUri = gitClient.GetRemoteUri(); - - var stacksForRemote = stackData.Stacks.Where(s => s.RemoteUri.Equals(remoteUri, StringComparison.OrdinalIgnoreCase)).ToList(); - - if (stacksForRemote.Count == 0) - { - logger.Information("No stacks found for current repository."); - return; - } - - var currentBranch = gitClient.GetCurrentBranch(); - var stack = inputProvider.SelectStack(logger, inputs.Stack, stacksForRemote, currentBranch); - - if (stack is null) - { - throw new InvalidOperationException($"Stack '{inputs.Stack}' not found."); - } - - var status = StackHelpers.GetStackStatus( - stack, - currentBranch, - logger, - gitClient, - gitHubClient, - true); - - var pullRequestsInStack = new List(); - - foreach (var branch in status.GetAllBranches()) - { - if (branch.PullRequest is not null) - { - pullRequestsInStack.Add(branch.PullRequest); - } - } - - if (pullRequestsInStack.Count == 0) - { - logger.Information($"No pull requests found for stack {stack.Name.Branch()}"); - return; - } - - StackHelpers.UpdateStackPullRequestDescription(inputProvider, stackConfig, stackData, stack); - StackHelpers.UpdateStackDescriptionInPullRequests(logger, gitHubClient, stack, pullRequestsInStack); - } -} \ No newline at end of file diff --git a/src/Stack/Config/Stack.cs b/src/Stack/Config/Stack.cs index 3b5c5035..69b5dadf 100644 --- a/src/Stack/Config/Stack.cs +++ b/src/Stack/Config/Stack.cs @@ -5,14 +5,6 @@ namespace Stack.Config; public record Stack(string Name, string RemoteUri, string SourceBranch, List Branches) { - public string? PullRequestDescription { get; private set; } - - public void SetPullRequestDescription(string description) - { - this.PullRequestDescription = description; - } - - public List GetAllBranches() { var branchesToReturn = new List(); diff --git a/src/Stack/Config/StackConfig.cs b/src/Stack/Config/StackConfig.cs index 2f107792..40a0a41f 100644 --- a/src/Stack/Config/StackConfig.cs +++ b/src/Stack/Config/StackConfig.cs @@ -123,7 +123,7 @@ private List LoadStacksFromV2Format(string jsonString) private static StackV2 MapToV2Format(Stack stack) { var branchesV2 = stack.Branches.Select(MapToV2Format).ToList(); - return new StackV2(stack.Name, stack.RemoteUri, stack.SourceBranch, branchesV2, stack.PullRequestDescription); + return new StackV2(stack.Name, stack.RemoteUri, stack.SourceBranch, branchesV2); } private static StackV2Branch MapToV2Format(Branch branch) @@ -145,14 +145,7 @@ private List LoadStacksFromV1Format(string jsonString) private static Stack MapFromV2Format(StackV2 stackV2) { var branches = stackV2.Branches.Select(b => new Branch(b.Name, [.. b.Children.Select(MapFromV2Format)])).ToList(); - var stack = new Stack(stackV2.Name, stackV2.RemoteUri, stackV2.SourceBranch, branches); - - if (stackV2.PullRequestDescription is not null) - { - stack.SetPullRequestDescription(stackV2.PullRequestDescription); - } - - return stack; + return new Stack(stackV2.Name, stackV2.RemoteUri, stackV2.SourceBranch, branches); } private static Branch MapFromV2Format(StackV2Branch branchV2) @@ -162,7 +155,7 @@ private static Branch MapFromV2Format(StackV2Branch branchV2) private static StackV1 MapToV1Format(Stack stack) { - return new StackV1(stack.Name, stack.RemoteUri, stack.SourceBranch, stack.AllBranchNames, stack.PullRequestDescription); + return new StackV1(stack.Name, stack.RemoteUri, stack.SourceBranch, stack.AllBranchNames); } private static Stack MapFromV1Format(StackV1 stackV1) @@ -185,17 +178,12 @@ private static Stack MapFromV1Format(StackV1 stackV1) currentParent = newBranch; } - var stack = new Stack(stackV1.Name, stackV1.RemoteUri, stackV1.SourceBranch, childBranches); - if (stackV1.PullRequestDescription is not null) - { - stack.SetPullRequestDescription(stackV1.PullRequestDescription); - } - return stack; + return new Stack(stackV1.Name, stackV1.RemoteUri, stackV1.SourceBranch, childBranches); } } -public record StackV1(string Name, string RemoteUri, string SourceBranch, List Branches, string? PullRequestDescription); -public record StackV2(string Name, string RemoteUri, string SourceBranch, List Branches, string? PullRequestDescription); +public record StackV1(string Name, string RemoteUri, string SourceBranch, List Branches); +public record StackV2(string Name, string RemoteUri, string SourceBranch, List Branches); public record StackV2Branch(string Name, List Children); public record StackConfigV2(List Stacks) diff --git a/src/Stack/Config/StackConstants.cs b/src/Stack/Config/StackConstants.cs index c2f926da..47096067 100644 --- a/src/Stack/Config/StackConstants.cs +++ b/src/Stack/Config/StackConstants.cs @@ -5,5 +5,5 @@ public static class StackConstants public const string StackMarkerText = "stack-pr-list"; public const string StackMarkerStart = $""; public const string StackMarkerEnd = $""; - public const string StackMarkerDescription = $""; + public const string StackMarkerDescription = $""; }