2
2
3
3
const getMetadata = require ( '../metadata' ) ;
4
4
const CLI = require ( '../../lib/cli' ) ;
5
- const cli = new CLI ( process . stderr ) ;
6
5
const Request = require ( '../../lib/request' ) ;
7
- const req = new Request ( ) ;
8
6
const {
9
- runPromise, runAsync , runSync , forceRunAsync
7
+ runPromise
10
8
} = require ( '../../lib/run' ) ;
11
- const Session = require ( '../../lib/landing_session' ) ;
12
- const dir = process . cwd ( ) ;
13
- const args = process . argv . slice ( 2 ) ;
9
+ const LandingSession = require ( '../../lib/landing_session' ) ;
14
10
15
11
const START = 'START' ;
16
12
const APPLY = 'APPLY' ;
@@ -28,9 +24,15 @@ const states = [
28
24
[ ABORT , ( args ) => args [ 0 ] === '--abort' ]
29
25
] ;
30
26
27
+ const cli = new CLI ( process . stderr ) ;
28
+ const req = new Request ( ) ;
29
+ const dir = process . cwd ( ) ;
30
+ const args = process . argv . slice ( 2 ) ;
31
+
31
32
const result = states . filter ( ( [ state , pred ] ) => pred ( args ) ) ;
32
33
if ( result . length ) {
33
- runPromise ( main ( result [ 0 ] [ 0 ] , args ) . catch ( ( err ) => {
34
+ const state = result [ 0 ] [ 0 ] ;
35
+ runPromise ( main ( state , args ) . catch ( ( err ) => {
34
36
if ( cli . spinner . enabled ) {
35
37
cli . spinner . fail ( ) ;
36
38
}
@@ -42,14 +44,13 @@ if (result.length) {
42
44
}
43
45
44
46
async function main ( state , args ) {
45
- let session ;
47
+ let session = new LandingSession ( cli , req , dir ) ;
46
48
47
49
try {
48
- session = Session . restore ( dir ) ;
50
+ session . restore ( ) ;
49
51
} catch ( err ) { // JSON error?
50
52
if ( state === ABORT ) {
51
- session = new Session ( dir ) ;
52
- await abort ( session ) ;
53
+ await session . abort ( ) ;
53
54
return ;
54
55
}
55
56
cli . warn (
@@ -66,246 +67,19 @@ async function main(state, args) {
66
67
cli . log ( 'run `git node land --abort` before starting a new session' ) ;
67
68
return ;
68
69
}
69
- session = new Session ( dir , parseInt ( args [ 0 ] ) ) ;
70
- await start ( session ) ;
70
+ session = new LandingSession ( cli , req , dir , parseInt ( args [ 0 ] ) ) ;
71
+ const { repo, owner, prid } = session ;
72
+ const metadata = await getMetadata ( { repo, owner, prid } , cli ) ;
73
+ return session . start ( metadata ) ;
71
74
} else if ( state === APPLY ) {
72
- await apply ( session ) ;
75
+ return session . apply ( ) ;
73
76
} else if ( state === AMEND ) {
74
- await amend ( session ) ;
77
+ return session . amend ( ) ;
75
78
} else if ( state === FINAL ) {
76
- await final ( session ) ;
79
+ return session . final ( ) ;
77
80
} else if ( state === ABORT ) {
78
- await abort ( session ) ;
81
+ return session . abort ( ) ;
79
82
} else if ( state === CONTINUE ) {
80
- await continueSession ( session ) ;
81
- }
82
- }
83
-
84
- async function start ( session ) {
85
- session . start ( ) ;
86
- const { repo, owner, prid } = session ;
87
- const result = await getMetadata ( { repo, owner, prid } , cli ) ;
88
-
89
- const status = result . status ? 'should be ready' : 'is not ready' ;
90
- const response = await cli . prompt (
91
- `This PR ${ status } to land, do you want to continue?` ) ;
92
- if ( response ) {
93
- session . saveMetadata ( result ) ;
94
- session . startApplying ( ) ;
95
- return apply ( session ) ;
96
- } else {
97
- await abort ( session ) ;
98
- process . exit ( ) ;
99
- }
100
- }
101
-
102
- function getNotYetPushedCommits ( session , verbose ) {
103
- const upstream = session . upstream ;
104
- const branch = session . branch ;
105
- var revs ;
106
- if ( verbose ) {
107
- revs = runSync ( 'git' ,
108
- [ 'log' , '--oneline' , `${ upstream } /${ branch } ...HEAD` ] ) ;
109
- } else {
110
- revs = runSync ( 'git' , [ 'rev-list' , `${ upstream } /${ branch } ...HEAD` ] ) ;
111
- }
112
-
113
- if ( ! revs . trim ( ) ) {
114
- return [ ] ;
115
- }
116
- return revs . trim ( ) . split ( '\n' ) ;
117
- }
118
-
119
- async function tryAbortAm ( session , cli ) {
120
- if ( session . amInProgress ( ) ) {
121
- const shouldAbortAm = await cli . prompt (
122
- 'Abort previous git am sessions?' ) ;
123
- if ( shouldAbortAm ) {
124
- await forceRunAsync ( 'git' , [ 'am' , '--abort' ] ) ;
125
- cli . ok ( 'Aborted previous git am sessions' ) ;
126
- }
127
- } else {
128
- cli . ok ( 'No git am in progress' ) ;
129
- }
130
- }
131
-
132
- async function tryAbortRebase ( session , cli ) {
133
- if ( session . rebaseInProgress ( ) ) {
134
- const shouldAbortRebase = await cli . prompt (
135
- 'Abort previous git rebase sessions?' ) ;
136
- if ( shouldAbortRebase ) {
137
- await forceRunAsync ( 'git' , [ 'rebase' , '--abort' ] ) ;
138
- cli . ok ( 'Aborted previous git rebase sessions' ) ;
139
- }
140
- } else {
141
- cli . ok ( 'No git rebase in progress' ) ;
142
- }
143
- }
144
-
145
- async function tryResetHead ( session , cli ) {
146
- const branch = `${ session . upstream } /${ session . branch } ` ;
147
- cli . startSpinner ( `Bringing ${ branch } up to date` ) ;
148
- await runAsync ( 'git' ,
149
- [ 'fetch' , session . upstream , session . branch ] ) ;
150
- cli . stopSpinner ( `${ branch } is now up-to-date` ) ;
151
- const notYetPushed = getNotYetPushedCommits ( session , true ) ;
152
- if ( notYetPushed . length ) {
153
- const branch = `${ session . upstream } /${ session . branch } ` ;
154
- cli . log ( `Found strayed commits in ${ branch } :\n` +
155
- ` - ${ notYetPushed . join ( '\n - ' ) } ` ) ;
156
- const shouldReset = await cli . prompt ( `Reset to ${ branch } ?` ) ;
157
- if ( shouldReset ) {
158
- await runAsync ( 'git' , [ 'reset' , '--hard' , branch ] ) ;
159
- cli . ok ( `Reset to ${ branch } ` ) ;
160
- }
161
- }
162
- }
163
-
164
- async function tryResetBranch ( session , cli ) {
165
- await tryAbortAm ( session , cli ) ;
166
- await tryAbortRebase ( session , cli ) ;
167
-
168
- const branch = `${ session . upstream } /${ session . branch } ` ;
169
- const shouldResetHead = await cli . prompt (
170
- `Do you want to try reset the branch to ${ branch } ?` ) ;
171
- if ( shouldResetHead ) {
172
- await tryResetHead ( session , cli ) ;
173
- }
174
- }
175
-
176
- async function abort ( session ) {
177
- session . abort ( ) ;
178
- await tryResetBranch ( session , cli ) ;
179
- cli . log ( `Aborted \`git node land\` session in ${ session . ncuDir } ` ) ;
180
- }
181
-
182
- async function apply ( session ) {
183
- if ( ! session . readyToApply ( ) ) {
184
- cli . warn ( 'This session can not proceed to apply patches, ' +
185
- 'run `git node land --abort`' ) ;
186
- return ;
187
- }
188
-
189
- await tryResetBranch ( session , cli ) ;
190
-
191
- const { repo, owner, prid } = session ;
192
- // TODO: restore previously downloaded patches
193
- cli . startSpinner ( `Downloading patch for ${ prid } ` ) ;
194
- const patch = await req . promise ( {
195
- url : `https://github.com/${ owner } /${ repo } /pull/${ prid } .patch`
196
- } ) ;
197
- session . savePatch ( patch ) ;
198
- cli . stopSpinner ( `Downloaded patch to ${ session . patchPath } ` ) ;
199
-
200
- // TODO: check that patches downloaded match metadata.commits
201
- await runAsync ( 'git' , [ 'am' , '--whitespace=fix' , session . patchPath ] ) ;
202
- cli . ok ( 'Patches applied' ) ;
203
-
204
- session . startAmending ( ) ;
205
- if ( / S u b j e c t : \[ P A T C H \] / . test ( patch ) ) {
206
- const shouldAmend = await cli . prompt (
207
- 'There is only one commit in this PR.\n' +
208
- 'do you want to amend the commit message?' ) ;
209
- if ( shouldAmend ) {
210
- const canFinal = await amend ( session ) ;
211
- if ( canFinal ) {
212
- return final ( session ) ;
213
- }
214
- }
215
- } else {
216
- const re = / S u b j e c t : \[ P A T C H 1 \/ ( \d + ) \] / ;
217
- const match = patch . match ( re ) ;
218
- if ( ! match ) {
219
- cli . warn ( 'Cannot get number of commits in the patch. ' +
220
- 'It seems to be malformed' ) ;
221
- return ;
222
- }
223
- const upstream = session . upstream ;
224
- const branch = session . branch ;
225
- cli . log (
226
- `There are ${ match [ 1 ] } commits in the PR.\n` +
227
- `Please run \`git rebase ${ upstream } /${ branch } -i\` ` +
228
- 'and use `git node land --amend` to amend the commit messages' ) ;
229
- // TODO: do git rebase automatically?
230
- }
231
- }
232
-
233
- async function amend ( session ) {
234
- if ( ! session . readyToAmend ( ) ) {
235
- cli . warn ( 'Not yet ready to amend, run `git node land --abort`' ) ;
236
- return ;
237
- }
238
-
239
- const rev = runSync ( 'git' , [ 'rev-parse' , 'HEAD' ] ) ;
240
- const original = runSync ( 'git' , [ 'show' , 'HEAD' , '-s' , '--format=%B' ] ) . trim ( ) ;
241
- const metadata = session . metadata . trim ( ) . split ( '\n' ) ;
242
- const amended = original . split ( '\n' ) ;
243
- if ( amended [ amended . length - 1 ] !== '' ) {
244
- amended . push ( '' ) ;
245
- }
246
-
247
- for ( const line of metadata ) {
248
- if ( original . includes ( line ) ) {
249
- if ( line ) {
250
- cli . warn ( `Found ${ line } , skipping..` ) ;
251
- }
252
- } else {
253
- amended . push ( line ) ;
254
- }
255
- }
256
-
257
- const message = amended . join ( '\n' ) + '\n' ;
258
- const messageFile = session . saveMessage ( rev , message ) ;
259
- cli . separator ( 'New Message' ) ;
260
- cli . log ( message . trim ( ) ) ;
261
- cli . separator ( ) ;
262
- const takeMessage = await cli . prompt ( 'Use this message?' ) ;
263
- if ( takeMessage ) {
264
- await runAsync ( 'git' , [ 'commit' , '--amend' , '-F' , messageFile ] ) ;
265
- // session.markAsAmended(rev);
266
- return true ;
267
- }
268
-
269
- cli . log ( `Please manually edit ${ messageFile } , then run\n` +
270
- `\`git commit --amend -F ${ messageFile } \` to finish amending the message` ) ;
271
- return false ;
272
- } ;
273
-
274
- async function final ( session ) {
275
- if ( ! session . readyToFinal ( ) ) { // check git rebase/am has been done
276
- cli . warn ( 'Not yet ready to final' ) ;
277
- return ;
278
- }
279
- const upstream = session . upstream ;
280
- const branch = session . branch ;
281
- const notYetPushed = getNotYetPushedCommits ( session ) ;
282
- const notYetPushedVerbose = getNotYetPushedCommits ( session , true ) ;
283
- await runAsync ( 'core-validate-commit' , notYetPushed ) ;
284
- cli . separator ( ) ;
285
- cli . log ( 'The following commits are ready to be pushed to ' +
286
- `${ upstream } /${ branch } ` ) ;
287
- cli . log ( `- ${ notYetPushedVerbose . join ( '\n- ' ) } ` ) ;
288
- cli . separator ( ) ;
289
- cli . log ( `run \`git push ${ upstream } ${ branch } \` to finish landing` ) ;
290
- const shouldClean = await cli . prompt ( 'Clean up generated temporary files?' ) ;
291
- if ( shouldClean ) {
292
- session . cleanFiles ( ) ;
293
- }
294
- }
295
-
296
- async function continueSession ( session ) {
297
- if ( session . readyToFinal ( ) ) {
298
- return final ( session ) ;
299
- }
300
- if ( session . readyToAmend ( ) ) {
301
- return amend ( session ) ;
302
- }
303
- if ( session . readyToApply ( ) ) {
304
- return apply ( session ) ;
305
- }
306
- if ( session . hasStarted ( ) ) {
307
- return apply ( session ) ;
83
+ return session . continue ( ) ;
308
84
}
309
- cli . log (
310
- 'Please run `git node land <PRID> to start a landing session`' ) ;
311
85
}
0 commit comments