@@ -341,6 +341,21 @@ public function handleRequest(AphrontRequest $request) {
341
341
->setKey ('commits ' )
342
342
->appendChild ($ local_table ));
343
343
344
+ $ stack_graph = id (new DifferentialStackGraph ())
345
+ ->setSeedRevision ($ revision )
346
+ ->loadGraph ();
347
+ if (!$ stack_graph ->isEmpty ()) {
348
+ $ stack_view = $ this ->renderStackView ($ revision , $ stack_graph );
349
+ list ($ stack_name , $ stack_color , $ stack_table ) = $ stack_view ;
350
+
351
+ $ tab_group ->addTab (
352
+ id (new PHUITabView ())
353
+ ->setName ($ stack_name )
354
+ ->setKey ('stack ' )
355
+ ->setColor ($ stack_color )
356
+ ->appendChild ($ stack_table ));
357
+ }
358
+
344
359
if ($ other_view ) {
345
360
$ tab_group ->addTab (
346
361
id (new PHUITabView ())
@@ -1198,4 +1213,149 @@ private function buildUnitMessagesView(
1198
1213
}
1199
1214
1200
1215
1216
+ private function renderStackView (
1217
+ DifferentialRevision $ current ,
1218
+ DifferentialStackGraph $ graph ) {
1219
+
1220
+ $ ancestry = $ graph ->getParentEdges ();
1221
+ $ viewer = $ this ->getViewer ();
1222
+
1223
+ $ revisions = id (new DifferentialRevisionQuery ())
1224
+ ->setViewer ($ viewer )
1225
+ ->withPHIDs (array_keys ($ ancestry ))
1226
+ ->execute ();
1227
+ $ revisions = mpull ($ revisions , null , 'getPHID ' );
1228
+
1229
+ $ order = id (new PhutilDirectedScalarGraph ())
1230
+ ->addNodes ($ ancestry )
1231
+ ->getTopographicallySortedNodes ();
1232
+
1233
+ $ ancestry = array_select_keys ($ ancestry , $ order );
1234
+
1235
+ $ traces = id (new PHUIDiffGraphView ())
1236
+ ->renderGraph ($ ancestry );
1237
+
1238
+ // Load author handles, and also revision handles for any revisions which
1239
+ // we failed to load (they might be policy restricted).
1240
+ $ handle_phids = mpull ($ revisions , 'getAuthorPHID ' );
1241
+ foreach ($ order as $ phid ) {
1242
+ if (empty ($ revisions [$ phid ])) {
1243
+ $ handle_phids [] = $ phid ;
1244
+ }
1245
+ }
1246
+ $ handles = $ viewer ->loadHandles ($ handle_phids );
1247
+
1248
+ $ rows = array ();
1249
+ $ rowc = array ();
1250
+
1251
+ $ ii = 0 ;
1252
+ $ seen = false ;
1253
+ foreach ($ ancestry as $ phid => $ ignored ) {
1254
+ $ revision = idx ($ revisions , $ phid );
1255
+ if ($ revision ) {
1256
+ $ status_icon = $ revision ->getStatusIcon ();
1257
+ $ status_name = $ revision ->getStatusDisplayName ();
1258
+
1259
+ $ status = array (
1260
+ id (new PHUIIconView ())->setIcon ($ status_icon ),
1261
+ ' ' ,
1262
+ $ status_name ,
1263
+ );
1264
+
1265
+ $ author = $ viewer ->renderHandle ($ revision ->getAuthorPHID ());
1266
+ $ title = phutil_tag (
1267
+ 'a ' ,
1268
+ array (
1269
+ 'href ' => $ revision ->getURI (),
1270
+ ),
1271
+ array (
1272
+ $ revision ->getMonogram (),
1273
+ ' ' ,
1274
+ $ revision ->getTitle (),
1275
+ ));
1276
+ } else {
1277
+ $ status = null ;
1278
+ $ author = null ;
1279
+ $ title = $ viewer ->renderHandle ($ phid );
1280
+ }
1281
+
1282
+ $ rows [] = array (
1283
+ $ traces [$ ii ++],
1284
+ $ status ,
1285
+ $ author ,
1286
+ $ title ,
1287
+ );
1288
+
1289
+ if ($ phid == $ current ->getPHID ()) {
1290
+ $ rowc [] = 'highlighted ' ;
1291
+ } else {
1292
+ $ rowc [] = null ;
1293
+ }
1294
+ }
1295
+
1296
+ $ stack_table = id (new AphrontTableView ($ rows ))
1297
+ ->setHeaders (
1298
+ array (
1299
+ null ,
1300
+ pht ('Status ' ),
1301
+ pht ('Author ' ),
1302
+ pht ('Revision ' ),
1303
+ ))
1304
+ ->setRowClasses ($ rowc )
1305
+ ->setColumnClasses (
1306
+ array (
1307
+ 'threads ' ,
1308
+ null ,
1309
+ null ,
1310
+ 'wide ' ,
1311
+ ));
1312
+
1313
+ // Count how many revisions this one depends on that are not yet closed.
1314
+ $ seen = array ();
1315
+ $ look = array ($ current ->getPHID ());
1316
+ while ($ look ) {
1317
+ $ phid = array_pop ($ look );
1318
+
1319
+ $ parents = idx ($ ancestry , $ phid , array ());
1320
+ foreach ($ parents as $ parent ) {
1321
+ if (isset ($ seen [$ parent ])) {
1322
+ continue ;
1323
+ }
1324
+
1325
+ $ seen [$ parent ] = $ parent ;
1326
+ $ look [] = $ parent ;
1327
+ }
1328
+ }
1329
+
1330
+ $ blocking_count = 0 ;
1331
+ foreach ($ seen as $ parent ) {
1332
+ if ($ parent == $ current ->getPHID ()) {
1333
+ continue ;
1334
+ }
1335
+
1336
+ $ revision = idx ($ revisions , $ parent );
1337
+ if (!$ revision ) {
1338
+ continue ;
1339
+ }
1340
+
1341
+ if ($ revision ->isClosed ()) {
1342
+ continue ;
1343
+ }
1344
+
1345
+ $ blocking_count ++;
1346
+ }
1347
+
1348
+ if (!$ blocking_count ) {
1349
+ $ stack_name = pht ('Stack ' );
1350
+ $ stack_color = null ;
1351
+ } else {
1352
+ $ stack_name = pht (
1353
+ 'Stack (%s Open) ' ,
1354
+ new PhutilNumber ($ blocking_count ));
1355
+ $ stack_color = PHUIListItemView::STATUS_FAIL ;
1356
+ }
1357
+
1358
+ return array ($ stack_name , $ stack_color , $ stack_table );
1359
+ }
1360
+
1201
1361
}
0 commit comments