3333$ creator = $ user ? $ user ->username : '' ;
3434$ created = time ();
3535
36+ /**
37+ * Check if the user has dropped their connection and delete the wiki if so
38+ *
39+ * We could check for dropped connections with register_shutdown_function(), but
40+ * that could happen in the middle of a shell command. If we tried to delete
41+ * a wiki while a shell command was running (e.g composer update) we may still
42+ * be left with stray files (e.g. /vendor)
43+ *
44+ * Instead manually check the connection at 'safe' times in between API requests
45+ * or shell commands.
46+ */
47+ function check_connection () {
48+ if ( connection_status () !== CONNECTION_NORMAL ) {
49+ abandon ( 'User disconnected early ' );
50+ }
51+ }
52+
53+ // Don't kill the process automatcally
54+ ignore_user_abort ( true );
55+
3656// Create an entry for the wiki before we have resolved patches.
3757// Will be updated later.
3858insert_wiki_data ( $ namePath , $ creator , $ created , $ branchDesc );
@@ -153,6 +173,7 @@ function set_progress( float $pc, string $label ) {
153173 $ o = 'CURRENT_REVISION ' ;
154174 }
155175 $ data = gerrit_query ( "changes/?q=change: $ query&o=LABELS&o= $ o " , true );
176+ check_connection ();
156177
157178 if ( count ( $ data ) === 0 ) {
158179 $ patch = htmlentities ( $ patch );
@@ -198,6 +219,7 @@ function set_progress( float $pc, string $label ) {
198219 // The patch doesn't have V+2, check if the uploader is trusted
199220 $ uploaderId = $ data [0 ]['revisions ' ][$ revision ]['uploader ' ]['_account_id ' ];
200221 $ uploader = gerrit_query ( 'accounts/ ' . $ uploaderId , true );
222+ check_connection ();
201223 if ( !is_trusted_user ( $ uploader ['email ' ] ) ) {
202224 abandon ( "Patch must be approved (Verified+2) by jenkins-bot, or uploaded by a trusted user " );
203225 }
@@ -220,6 +242,7 @@ function set_progress( float $pc, string $label ) {
220242
221243 // Look at all commits in this patch's tree for cross-repo dependencies to add
222244 $ data = gerrit_query ( "changes/ $ id/revisions/ $ revision/related " , true );
245+ check_connection ();
223246 // Ancestor commits only, not descendants
224247 $ foundCurr = false ;
225248 foreach ( $ data ['changes ' ] as $ change ) {
@@ -232,6 +255,7 @@ function set_progress( float $pc, string $label ) {
232255
233256 foreach ( $ relatedChanges as [ $ c , $ r ] ) {
234257 $ data = gerrit_query ( "changes/ $ c/revisions/ $ r/commit " , true );
258+ check_connection ();
235259
236260 preg_match_all ( '/^Depends-On: (.+)$/m ' , $ data ['message ' ], $ m );
237261 foreach ( $ m [1 ] as $ changeid ) {
@@ -266,6 +290,7 @@ function set_progress( float $pc, string $label ) {
266290 list ( $ t , $ r , $ p ) = $ matches ;
267291
268292 $ data = gerrit_query ( "changes/ $ r/revisions/ $ p/commit " , true );
293+ check_connection ();
269294 if ( $ data ) {
270295 $ t = $ t . ': ' . $ data [ 'subject ' ];
271296 get_linked_tasks ( $ data ['message ' ], $ linkedTasks );
@@ -332,6 +357,7 @@ function set_progress( float $pc, string $label ) {
332357foreach ( $ repos as $ source => $ target ) {
333358 set_progress ( $ repoProgress , "Updating repositories ( $ n/ $ repoCount)... " );
334359
360+ check_connection ();
335361 $ error = shell_echo ( __DIR__ . '/new/updaterepos.sh ' ,
336362 $ baseEnv + [
337363 'REPO_SOURCE ' => $ source ,
@@ -347,6 +373,7 @@ function set_progress( float $pc, string $label ) {
347373}
348374
349375// Just creates empty folders so no need for progress update
376+ check_connection ();
350377$ error = shell_echo ( __DIR__ . '/new/precheckout.sh ' , $ baseEnv );
351378if ( $ error ) {
352379 abandon ( "Could not create directories for wiki " );
@@ -360,6 +387,7 @@ function set_progress( float $pc, string $label ) {
360387foreach ( $ repos as $ source => $ target ) {
361388 set_progress ( $ repoProgress , "Checking out repositories ( $ n/ $ repoCount)... " );
362389
390+ check_connection ();
363391 $ error = shell_echo ( __DIR__ . '/new/checkout.sh ' ,
364392 $ baseEnv + [
365393 'BRANCH ' => $ branch ,
@@ -377,6 +405,7 @@ function set_progress( float $pc, string $label ) {
377405
378406// TODO: Make this a loop
379407set_progress ( 60 , 'Fetching submodules... ' );
408+ check_connection ();
380409$ error = shell_echo ( __DIR__ . '/new/submodules.sh ' , $ baseEnv );
381410if ( $ error ) {
382411 abandon ( "Could not fetch submodules " );
@@ -397,6 +426,7 @@ static function ( string $repo ) use ( $repos ): bool {
397426foreach ( $ composerInstallRepos as $ i => $ repo ) {
398427 $ n = $ i + 1 ;
399428 set_progress ( $ repoProgress , "Fetching dependencies ( $ n/ $ repoCount)... " );
429+ check_connection ();
400430 $ error = shell_echo ( __DIR__ . '/new/composerinstall.sh ' ,
401431 $ baseEnv + [
402432 // Variable used by composer itself, not our script
@@ -413,6 +443,7 @@ static function ( string $repo ) use ( $repos ): bool {
413443
414444set_progress ( 65 , 'Installing your wiki... ' );
415445
446+ check_connection ();
416447$ error = shell_echo ( __DIR__ . '/new/install.sh ' ,
417448 $ baseEnv + [
418449 'WIKINAME ' => $ wikiName ,
@@ -433,6 +464,7 @@ static function ( string $repo ) use ( $repos ): bool {
433464foreach ( $ commands as $ i => $ command ) {
434465 $ n = $ i + 1 ;
435466 set_progress ( $ progress , "Fetching and applying patches ( $ n/ $ count)... " );
467+ check_connection ();
436468 $ error = shell_echo ( $ command [1 ], $ baseEnv + $ command [0 ] );
437469 if ( $ error ) {
438470 abandon ( "Could not apply patch {$ patchesApplied [$ i ]}" );
@@ -442,6 +474,7 @@ static function ( string $repo ) use ( $repos ): bool {
442474
443475set_progress ( 90 , 'Setting up wiki content... ' );
444476
477+ check_connection ();
445478$ error = shell_echo ( __DIR__ . '/new/postinstall.sh ' ,
446479 $ baseEnv + [
447480 'MAINPAGE ' => $ mainPage ,
0 commit comments