Skip to content
This repository was archived by the owner on May 20, 2020. It is now read-only.

Commit 858ae5b

Browse files
author
Samuel Parkinson
authored
Merge pull request #50 from Financial-Times/pulls-merge
refactor: require a pull request url for the `pulls merge` command
2 parents 9691eb6 + 3b13a49 commit 858ae5b

File tree

3 files changed

+56
-63
lines changed

3 files changed

+56
-63
lines changed

lib/common-yargs.js

+16
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ const withTitle = yargs => yargs.option("title", {
7575
type: "string",
7676
})
7777

78+
const withPullRequest = yargs => yargs.positional("pull-request", {
79+
describe: "Pull request URL, e.g. https://github.com/foo/bar/pull/3",
80+
type: "string",
81+
coerce: pullRequest => {
82+
const re = /https:\/\/github\.com\/(?<owner>.+)\/(?<repo>.+)\/pull\/(?<number>\d+)/;
83+
const matches = re.exec(pullRequest);
84+
85+
if (matches === null) {
86+
throw new Error(`"${pullRequest}" is not a valid pull request URL`);
87+
}
88+
89+
return matches.groups;
90+
}
91+
});
92+
7893
module.exports = {
7994
descriptions,
8095
withToken,
@@ -87,4 +102,5 @@ module.exports = {
87102
withTeamReviewers,
88103
withBody,
89104
withTitle,
105+
withPullRequest,
90106
}

src/commands/pulls/merge.js

+21-56
Original file line numberDiff line numberDiff line change
@@ -17,77 +17,42 @@ const builder = yargs => {
1717
const baseOptions = flow([
1818
commonYargs.withToken,
1919
commonYargs.withJson,
20-
commonYargs.withBase,
21-
commonYargs.withOwner,
22-
commonYargs.withRepo,
23-
commonYargs.withNumber,
24-
])
20+
commonYargs.withPullRequest,
21+
]);
22+
2523
return baseOptions(yargs)
26-
.option("commit_title", {
27-
alias: "t",
28-
describe: "Pull request commit title",
29-
type: "string"
30-
})
31-
.option("commit_message", {
32-
alias: "m",
33-
describe: "Pull request commit message",
34-
type: "string"
35-
})
36-
.option("sha", {
37-
describe: "SHA that the pull request head must match to allow merge",
38-
type: "string"
39-
})
40-
.option("merge_method", {
41-
describe: "Merge method to use. Possible values are merge, squash or rebase. Default is merge.",
42-
type: "string"
43-
})
24+
.option("method", {
25+
describe: "Merge method to use.",
26+
choices: ["merge", "squash", "rebase"],
27+
default: "merge"
28+
});
4429
}
4530

4631
/**
4732
* Return the contents of a pull request body and create a pull request.
4833
*
4934
* @param {object} argv - argv parsed and filtered by yargs
50-
* @param {string} argv.token
51-
* @param {string} argv.json
52-
* @param {string} argv.owner
53-
* @param {string} argv.repo
54-
* @param {string} argv.number
55-
* @param {string} [argv.commit_title]
56-
* @param {string} [argv.commit_message]
57-
* @param {string} [argv.sha]
58-
* @param {string} [argv.merge_method]
5935
* @throws {Error} - Throws an error if any required properties are invalid
6036
*/
61-
const handler = async ({ token, json, owner, repo, number, commit_title, commit_message, sha, merge_method }) => {
37+
const handler = async (argv) => {
38+
try {
39+
const octokit = await authenticatedOctokit({ personalAccessToken: argv.token });
6240

63-
// Ensure that all required properties have values
64-
const requiredProperties = {
65-
owner,
66-
repo,
67-
number,
68-
}
69-
if (Object.values(requiredProperties).some(property => !property)) {
70-
throw new Error(`Please provide all required properties: ${Object.keys(requiredProperties).join(", ")}`)
71-
}
41+
const result = await octokit.pulls.merge({
42+
owner: argv.pullRequest.owner,
43+
repo: argv.pullRequest.repo,
44+
pull_number: argv.pullRequest.number,
45+
merge_method: argv.method,
46+
});
7247

73-
const inputs = Object.assign({}, requiredProperties, {
74-
commit_title,
75-
commit_message,
76-
sha,
77-
merge_method,
78-
})
79-
try {
80-
const octokit = await authenticatedOctokit({ personalAccessToken: token })
81-
const result = await octokit.pulls.merge(inputs)
82-
printOutput({ json, resource: result })
83-
}
84-
catch (error) {
85-
throw new Error(error)
48+
printOutput({ json: argv.json, resource: result });
49+
} catch (error) {
50+
throw new Error(error);
8651
}
8752
}
8853

8954
module.exports = {
90-
command: "merge",
55+
command: "merge <pull-request>",
9156
desc: "Merge an existing pull request",
9257
builder,
9358
handler

test/commands/pulls/merge.test.js

+19-7
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,22 @@ describe("Yargs", () => {
3434
expect(console.warn).not.toBeCalled()
3535
})
3636

37+
test("an invalid pull request URL errors", async () => {
38+
expect.assertions(1)
39+
try {
40+
const testOptions = {
41+
token: "test",
42+
pullRequest: "foo-bar",
43+
};
44+
await yargsModule.handler(testOptions)
45+
} catch (error) {
46+
expect(error).toBeInstanceOf(Error)
47+
}
48+
})
49+
3750
const requiredOptions = {
3851
token: "test",
39-
owner: "test",
40-
repo: "test",
41-
number: "test",
52+
pullRequest: "https://github.com/test/test/",
4253
}
4354
for (let option of Object.keys(requiredOptions)) {
4455
test(`Running the command handler without '${option}' throws an error`, async () => {
@@ -55,7 +66,6 @@ describe("Yargs", () => {
5566
})
5667

5768
describe("Octokit", () => {
58-
5969
// If this endpoint is not called, nock.isDone() will be false.
6070
nock('https://api.github.com')
6171
.persist()
@@ -65,9 +75,11 @@ describe("Octokit", () => {
6575
test("running the command handler triggers a network request of the GitHub API", async () => {
6676
await yargsModule.handler({
6777
token: "test",
68-
owner: "test",
69-
repo: "test",
70-
number: 1,
78+
pullRequest: {
79+
owner: "test",
80+
repo: "test",
81+
number: 1
82+
},
7183
})
7284
expect(nock.isDone()).toBe(true)
7385
})

0 commit comments

Comments
 (0)