|
1 | | -/* eslint-disable @typescript-eslint/no-non-null-assertion */ |
2 | | - |
3 | 1 | import commander from "commander"; |
4 | 2 | import { join } from "path"; |
5 | 3 | import { Bedrock, Config } from "../../config"; |
@@ -29,6 +27,16 @@ export interface CommandOptions { |
29 | 27 | targetBranch: string | undefined; |
30 | 28 | } |
31 | 29 |
|
| 30 | +export interface CommandValues { |
| 31 | + sourceBranch: string; |
| 32 | + title: string | undefined; |
| 33 | + description: string; |
| 34 | + remoteUrl: string; |
| 35 | + personalAccessToken: string; |
| 36 | + orgName: string; |
| 37 | + targetBranch: string | undefined; |
| 38 | +} |
| 39 | + |
32 | 40 | export const getRemoteUrl = async ( |
33 | 41 | remoteUrl: string | undefined |
34 | 42 | ): Promise<string> => { |
@@ -99,70 +107,85 @@ export const getSourceBranch = async ( |
99 | 107 | /** |
100 | 108 | * Creates a pull request from the given source branch |
101 | 109 | * @param defaultRings List of default rings |
102 | | - * @param opts option values |
| 110 | + * @param values option values |
103 | 111 | */ |
104 | 112 | export const makePullRequest = async ( |
105 | 113 | defaultRings: string[], |
106 | | - opts: CommandOptions |
| 114 | + values: CommandValues |
107 | 115 | ): Promise<void> => { |
108 | 116 | for (const ring of defaultRings) { |
109 | | - const title = opts.title || `[SPK] ${opts.sourceBranch} => ${ring}`; |
110 | | - await createPullRequest(title, opts.sourceBranch!, ring, { |
111 | | - description: opts.description!, |
112 | | - orgName: opts.orgName!, |
113 | | - originPushUrl: opts.remoteUrl!, |
114 | | - personalAccessToken: opts.personalAccessToken!, |
| 117 | + const title = values.title || `[SPK] ${values.sourceBranch} => ${ring}`; |
| 118 | + await createPullRequest(title, values.sourceBranch, ring, { |
| 119 | + description: values.description, |
| 120 | + orgName: values.orgName, |
| 121 | + originPushUrl: values.remoteUrl, |
| 122 | + personalAccessToken: values.personalAccessToken, |
115 | 123 | }); |
116 | 124 | } |
117 | 125 | }; |
118 | 126 |
|
| 127 | +const populateValues = async (opts: CommandOptions): Promise<CommandValues> => { |
| 128 | + const { azure_devops } = Config(); |
| 129 | + opts.orgName = opts.orgName || azure_devops?.org; |
| 130 | + opts.personalAccessToken = |
| 131 | + opts.personalAccessToken || azure_devops?.access_token; |
| 132 | + |
| 133 | + // Default the remote to the git origin |
| 134 | + opts.remoteUrl = await getRemoteUrl(opts.remoteUrl); |
| 135 | + |
| 136 | + // default pull request source branch to the current branch |
| 137 | + opts.sourceBranch = await getSourceBranch(opts.sourceBranch); |
| 138 | + |
| 139 | + const errors = validateForRequiredValues(decorator, { |
| 140 | + orgName: opts.orgName, |
| 141 | + personalAccessToken: opts.personalAccessToken, |
| 142 | + remoteUrl: opts.remoteUrl, |
| 143 | + sourceBranch: opts.sourceBranch, |
| 144 | + }); |
| 145 | + if (errors.length > 0) { |
| 146 | + throw Error("missing required values"); |
| 147 | + } |
| 148 | + |
| 149 | + return { |
| 150 | + // validateForRequiredValues confirm that sourceBranch has value |
| 151 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 152 | + sourceBranch: opts.sourceBranch!, |
| 153 | + title: opts.title, |
| 154 | + description: opts.description || "This is automated PR generated via SPK", |
| 155 | + remoteUrl: opts.remoteUrl, |
| 156 | + // validateForRequiredValues confirm that personalAccessToken has value |
| 157 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 158 | + personalAccessToken: opts.personalAccessToken!, |
| 159 | + // validateForRequiredValues confirm that orgName has value |
| 160 | + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 161 | + orgName: opts.orgName!, |
| 162 | + targetBranch: opts.targetBranch, |
| 163 | + }; |
| 164 | +}; |
| 165 | + |
119 | 166 | export const execute = async ( |
120 | 167 | opts: CommandOptions, |
121 | 168 | exitFn: (status: number) => Promise<void> |
122 | 169 | ): Promise<void> => { |
123 | 170 | try { |
124 | | - const { azure_devops } = Config(); |
125 | | - opts.orgName = opts.orgName || azure_devops?.org; |
126 | | - opts.personalAccessToken = |
127 | | - opts.personalAccessToken || azure_devops?.access_token!; |
128 | | - opts.description = |
129 | | - opts.description || "This is automated PR generated via SPK"; |
130 | | - |
131 | | - //////////////////////////////////////////////////////////////////////// |
132 | | - // Give defaults |
133 | | - //////////////////////////////////////////////////////////////////////// |
| 171 | + const values = await populateValues(opts); |
| 172 | + |
134 | 173 | // default pull request against initial ring |
135 | 174 | const bedrockConfig = Bedrock(); |
136 | 175 | // Default to the --target-branch for creating a revision; if not specified, fallback to default rings in bedrock.yaml |
137 | | - const defaultRings = getDefaultRings(opts.targetBranch, bedrockConfig); |
138 | | - |
139 | | - // default pull request source branch to the current branch |
140 | | - opts.sourceBranch = await getSourceBranch(opts.sourceBranch); |
| 176 | + const defaultRings = getDefaultRings(values.targetBranch, bedrockConfig); |
141 | 177 |
|
142 | 178 | // Make sure the user isn't trying to make a PR for a branch against itself |
143 | | - if (defaultRings.includes(opts.sourceBranch)) { |
| 179 | + if (defaultRings.includes(values.sourceBranch)) { |
144 | 180 | throw Error( |
145 | 181 | `A pull request for a branch cannot be made against itself. Ensure your target branch(es) '${JSON.stringify( |
146 | 182 | defaultRings |
147 | | - )}' do not include your source branch '${opts.sourceBranch}'` |
| 183 | + )}' do not include your source branch '${values.sourceBranch}'` |
148 | 184 | ); |
149 | 185 | } |
150 | 186 |
|
151 | | - // Default the remote to the git origin |
152 | | - opts.remoteUrl = await getRemoteUrl(opts.remoteUrl); |
153 | | - const errors = validateForRequiredValues(decorator, { |
154 | | - orgName: opts.orgName, |
155 | | - personalAccessToken: opts.personalAccessToken, |
156 | | - remoteUrl: opts.remoteUrl, |
157 | | - sourceBranch: opts.sourceBranch, |
158 | | - }); |
159 | | - |
160 | | - if (errors.length > 0) { |
161 | | - await exitFn(1); |
162 | | - } else { |
163 | | - await makePullRequest(defaultRings, opts); |
164 | | - await exitFn(0); |
165 | | - } |
| 187 | + await makePullRequest(defaultRings, values); |
| 188 | + await exitFn(0); |
166 | 189 | } catch (err) { |
167 | 190 | logger.error(err); |
168 | 191 | await exitFn(1); |
|
0 commit comments