Fossil SCM

The backoffice now invokes after-receive hooks.

drh 2020-07-06 10:21 hooks
Commit 4777999d32b65002b6f38ce09a97d8a19d0f2f8b59243c2dd75a55d58256c674
--- src/backoffice.c
+++ src/backoffice.c
@@ -19,10 +19,11 @@
1919
** occur after user interaction with the repository. Examples of
2020
** backoffice processing includes:
2121
**
2222
** * Sending alerts and notifications
2323
** * Processing the email queue
24
+** * Handling post-receive hooks
2425
** * Automatically syncing to peer repositories
2526
**
2627
** Backoffice processing is automatically started whenever there are
2728
** changes to the repository. The backoffice process dies off after
2829
** a period of inactivity.
@@ -627,10 +628,12 @@
627628
/* Here is where the actual work of the backoffice happens */
628629
nThis = alert_backoffice(0);
629630
if( nThis ){ backoffice_log("%d alerts", nThis); nTotal += nThis; }
630631
nThis = smtp_cleanup();
631632
if( nThis ){ backoffice_log("%d SMTPs", nThis); nTotal += nThis; }
633
+ nThis = hook_backoffice();
634
+ if( nThis ){ backoffice_log("%d hooks", nThis); nTotal += nThis; }
632635
633636
/* Close the log */
634637
if( backofficeFILE ){
635638
if( nTotal || backofficeLogDetail ){
636639
if( nTotal==0 ) backoffice_log("no-op");
637640
--- src/backoffice.c
+++ src/backoffice.c
@@ -19,10 +19,11 @@
19 ** occur after user interaction with the repository. Examples of
20 ** backoffice processing includes:
21 **
22 ** * Sending alerts and notifications
23 ** * Processing the email queue
 
24 ** * Automatically syncing to peer repositories
25 **
26 ** Backoffice processing is automatically started whenever there are
27 ** changes to the repository. The backoffice process dies off after
28 ** a period of inactivity.
@@ -627,10 +628,12 @@
627 /* Here is where the actual work of the backoffice happens */
628 nThis = alert_backoffice(0);
629 if( nThis ){ backoffice_log("%d alerts", nThis); nTotal += nThis; }
630 nThis = smtp_cleanup();
631 if( nThis ){ backoffice_log("%d SMTPs", nThis); nTotal += nThis; }
 
 
632
633 /* Close the log */
634 if( backofficeFILE ){
635 if( nTotal || backofficeLogDetail ){
636 if( nTotal==0 ) backoffice_log("no-op");
637
--- src/backoffice.c
+++ src/backoffice.c
@@ -19,10 +19,11 @@
19 ** occur after user interaction with the repository. Examples of
20 ** backoffice processing includes:
21 **
22 ** * Sending alerts and notifications
23 ** * Processing the email queue
24 ** * Handling post-receive hooks
25 ** * Automatically syncing to peer repositories
26 **
27 ** Backoffice processing is automatically started whenever there are
28 ** changes to the repository. The backoffice process dies off after
29 ** a period of inactivity.
@@ -627,10 +628,12 @@
628 /* Here is where the actual work of the backoffice happens */
629 nThis = alert_backoffice(0);
630 if( nThis ){ backoffice_log("%d alerts", nThis); nTotal += nThis; }
631 nThis = smtp_cleanup();
632 if( nThis ){ backoffice_log("%d SMTPs", nThis); nTotal += nThis; }
633 nThis = hook_backoffice();
634 if( nThis ){ backoffice_log("%d hooks", nThis); nTotal += nThis; }
635
636 /* Close the log */
637 if( backofficeFILE ){
638 if( nTotal || backofficeLogDetail ){
639 if( nTotal==0 ) backoffice_log("no-op");
640
+49
--- src/hook.c
+++ src/hook.c
@@ -352,5 +352,54 @@
352352
{
353353
fossil_fatal("unknown command \"%s\" - should be one of: "
354354
"add delete edit list test", zCmd);
355355
}
356356
}
357
+
358
+/*
359
+** The backoffice calls this routine to run the after-receive hooks.
360
+*/
361
+int hook_backoffice(void){
362
+ Stmt q;
363
+ const char *zLastRcvid = 0;
364
+ char *zNewRcvid = 0;
365
+ Blob chng;
366
+ int cnt = 0;
367
+ db_begin_write();
368
+ if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
369
+ goto hook_backoffice_done; /* No hooks */
370
+ }
371
+ zLastRcvid = db_get("hook-last-rcvid","0");
372
+ zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
373
+ if( atoi(zLastRcvid)>=atoi(zNewRcvid) ){
374
+ goto hook_backoffice_done; /* no new content */
375
+ }
376
+ blob_init(&chng, 0, 0);
377
+ db_prepare(&q,
378
+ "SELECT json_extract(jx.value,'$.cmd') "
379
+ " FROM config, json_each(config.value) AS jx"
380
+ " WHERE config.name='hooks' AND json_valid(config.value)"
381
+ " AND json_extract(jx.value,'$.type')='after-receive'"
382
+ " ORDER BY json_extract(jx.value,'$.seq');"
383
+ );
384
+ while( db_step(&q)==SQLITE_ROW ){
385
+ char *zCmd;
386
+ FILE *f;
387
+ if( cnt==0 ){
388
+ hook_changes(&chng, zLastRcvid, 0);
389
+ }
390
+ zCmd = hook_subst(db_column_text(&q,0));
391
+ f = popen(zCmd, "w");
392
+ if( f ){
393
+ fwrite(blob_buffer(&chng),1,blob_size(&chng),f);
394
+ pclose(f);
395
+ }
396
+ fossil_free(zCmd);
397
+ cnt++;
398
+ }
399
+ db_finalize(&q);
400
+ db_set("hook-last-rcvid", zNewRcvid, 0);
401
+ blob_reset(&chng);
402
+hook_backoffice_done:
403
+ db_commit_transaction();
404
+ return cnt;
405
+}
357406
--- src/hook.c
+++ src/hook.c
@@ -352,5 +352,54 @@
352 {
353 fossil_fatal("unknown command \"%s\" - should be one of: "
354 "add delete edit list test", zCmd);
355 }
356 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
--- src/hook.c
+++ src/hook.c
@@ -352,5 +352,54 @@
352 {
353 fossil_fatal("unknown command \"%s\" - should be one of: "
354 "add delete edit list test", zCmd);
355 }
356 }
357
358 /*
359 ** The backoffice calls this routine to run the after-receive hooks.
360 */
361 int hook_backoffice(void){
362 Stmt q;
363 const char *zLastRcvid = 0;
364 char *zNewRcvid = 0;
365 Blob chng;
366 int cnt = 0;
367 db_begin_write();
368 if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
369 goto hook_backoffice_done; /* No hooks */
370 }
371 zLastRcvid = db_get("hook-last-rcvid","0");
372 zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
373 if( atoi(zLastRcvid)>=atoi(zNewRcvid) ){
374 goto hook_backoffice_done; /* no new content */
375 }
376 blob_init(&chng, 0, 0);
377 db_prepare(&q,
378 "SELECT json_extract(jx.value,'$.cmd') "
379 " FROM config, json_each(config.value) AS jx"
380 " WHERE config.name='hooks' AND json_valid(config.value)"
381 " AND json_extract(jx.value,'$.type')='after-receive'"
382 " ORDER BY json_extract(jx.value,'$.seq');"
383 );
384 while( db_step(&q)==SQLITE_ROW ){
385 char *zCmd;
386 FILE *f;
387 if( cnt==0 ){
388 hook_changes(&chng, zLastRcvid, 0);
389 }
390 zCmd = hook_subst(db_column_text(&q,0));
391 f = popen(zCmd, "w");
392 if( f ){
393 fwrite(blob_buffer(&chng),1,blob_size(&chng),f);
394 pclose(f);
395 }
396 fossil_free(zCmd);
397 cnt++;
398 }
399 db_finalize(&q);
400 db_set("hook-last-rcvid", zNewRcvid, 0);
401 blob_reset(&chng);
402 hook_backoffice_done:
403 db_commit_transaction();
404 return cnt;
405 }
406

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button