Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 2 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<!-- stack-pr-list -->` 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

Expand Down Expand Up @@ -423,21 +423,6 @@ OPTIONS:
-s, --stack The name of the stack to open PRs for
```

#### `stack pr description` <!-- omit from toc -->

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 <!-- omit from toc -->

#### `stack config open` <!-- omit from toc -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>()).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}";

Expand All @@ -82,7 +79,7 @@ private static EquivalencyAssertionOptions<Dictionary<string, GitHubPullRequest>
}

[Fact]
public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPullRequestHasTheCorrectStackDescription()
public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPullRequestHasTheCorrectPullRequestList()
{
// Arrange
var sourceBranch = Some.BranchName();
Expand Down Expand Up @@ -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<string>()).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();
Expand Down Expand Up @@ -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<string>()).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]
Expand Down Expand Up @@ -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<string>()).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}";

Expand Down Expand Up @@ -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<string>()).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}";

Expand Down Expand Up @@ -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<string>()).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}";

Expand Down Expand Up @@ -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<string>()).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";
Expand Down Expand Up @@ -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<IInputProvider>();
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<string[]>()).Returns("Stack1");
inputProvider
.MultiSelect(Questions.SelectPullRequestsToCreate, Arg.Any<PullRequestCreateAction[]>(), true, Arg.Any<Func<PullRequestCreateAction, string>>())
.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<string, GitHubPullRequest>
{
[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<string>());
}
}
Loading