77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/*
** Translate a hook command string into its executable format by
** converting every %-substitutions as follows:
**
** %F -> Name of the fossil executable
** %R -> Name of the repository
**
** The returned string is obtained from fossil_malloc() and should
** be freed by the caller.
*/
char *hook_subst(const char *zCmd){
Blob r;
int i;
blob_init(&r, 0, 0);
while( zCmd[0] ){
for(i=0; zCmd[i] && zCmd[i]!='%'; i++){}
blob_append(&r, zCmd, i);
if( zCmd[i]==0 ) break;
if( zCmd[i+1]=='F' ){
blob_append(&r, g.nameOfExe, -1);
zCmd += i+2;
}else if( zCmd[i+1]=='R' ){
blob_append(&r, g.zRepositoryName, -1);
zCmd += i+2;
}else{
blob_append(&r, zCmd+i, 1);
zCmd += i+1;
}
}
blob_str(&r);
return r.aData;
|
>
>
|
>
>
>
>
>
|
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
** Translate a hook command string into its executable format by
** converting every %-substitutions as follows:
**
** %F -> Name of the fossil executable
** %R -> Name of the repository
** %A -> Auxiliary information filename (might be empty string)
**
** The returned string is obtained from fossil_malloc() and should
** be freed by the caller.
*/
static char *hook_subst(
const char *zCmd,
const char *zAuxFilename /* Name of auxiliary information file */
){
Blob r;
int i;
blob_init(&r, 0, 0);
while( zCmd[0] ){
for(i=0; zCmd[i] && zCmd[i]!='%'; i++){}
blob_append(&r, zCmd, i);
if( zCmd[i]==0 ) break;
if( zCmd[i+1]=='F' ){
blob_append(&r, g.nameOfExe, -1);
zCmd += i+2;
}else if( zCmd[i+1]=='R' ){
blob_append(&r, g.zRepositoryName, -1);
zCmd += i+2;
}else if( zCmd[i+1]=='A' ){
if( zAuxFilename ) blob_append(&r, zAuxFilename, -1);
zCmd += i+2;
}else{
blob_append(&r, zCmd+i, 1);
zCmd += i+1;
}
}
blob_str(&r);
return r.aData;
|
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
** hook processing. Used for debugging.
**
** > fossil hook test [OPTIONS] ID
**
** Run the hook script given by ID for testing purposes.
** Options:
**
** --dry-run Print the script on stdout rather than run it
** --base-rcvid N Pretend that the hook-last-rcvid value is N
** --new-rcvid M Pretend that the last rcvid valud is M
**
** The --base-rcvid and --new-rcvid options are silently ignored if
** the hook type is not "after-receive". The default values for
** --base-rcvid and --new-rcvid cause the last recieve to be processed.
*/
void hook_cmd(void){
const char *zCmd;
|
|
|
|
>
|
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
** hook processing. Used for debugging.
**
** > fossil hook test [OPTIONS] ID
**
** Run the hook script given by ID for testing purposes.
** Options:
**
** --dry-run Print the script on stdout rather than run it
** --base-rcvid N Pretend that the hook-last-rcvid value is N
** --new-rcvid M Pretend that the last rcvid valud is M
** --aux-file NAME NAME is substituted for %A in the script
**
** The --base-rcvid and --new-rcvid options are silently ignored if
** the hook type is not "after-receive". The default values for
** --base-rcvid and --new-rcvid cause the last recieve to be processed.
*/
void hook_cmd(void){
const char *zCmd;
|
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
db_finalize(&q);
}else
if( strncmp(zCmd, "test", nCmd)==0 ){
Stmt q;
int bDryRun = find_option("dry-run", "n", 0)!=0;
const char *zOrigRcvid = find_option("base-rcvid",0,1);
const char *zNewRcvid = find_option("new-rcvid",0,1);
verify_all_options();
if( g.argc<4 ) usage("test ID");
int id = atoi(g.argv[3]);
if( zOrigRcvid==0 ){
zOrigRcvid = db_text(0, "SELECT max(rcvid)-1 FROM rcvfrom");
}
db_prepare(&q,
"SELECT json_extract(value,'$[%d].cmd'), "
" json_extract(value,'$[%d].type')=='after-receive'"
" FROM config"
" WHERE name='hooks' AND json_valid(value)",
id, id
);
while( db_step(&q)==SQLITE_ROW ){
const char *zCmd = db_column_text(&q,0);
char *zCmd2 = hook_subst(zCmd);
int needOut = db_column_int(&q,1);
Blob out;
blob_init(&out,0,0);
if( needOut ) hook_changes(&out, zOrigRcvid, zNewRcvid);
if( bDryRun ){
fossil_print("%s\n", zCmd2);
if( needOut ){
|
>
|
|
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
|
db_finalize(&q);
}else
if( strncmp(zCmd, "test", nCmd)==0 ){
Stmt q;
int bDryRun = find_option("dry-run", "n", 0)!=0;
const char *zOrigRcvid = find_option("base-rcvid",0,1);
const char *zNewRcvid = find_option("new-rcvid",0,1);
const char *zAuxFilename = find_option("aux-file",0,1);
verify_all_options();
if( g.argc<4 ) usage("test ID");
int id = atoi(g.argv[3]);
if( zOrigRcvid==0 ){
zOrigRcvid = db_text(0, "SELECT max(rcvid)-1 FROM rcvfrom");
}
db_prepare(&q,
"SELECT json_extract(value,'$[%d].cmd'), "
" json_extract(value,'$[%d].type')=='after-receive'"
" FROM config"
" WHERE name='hooks' AND json_valid(value)",
id, id
);
while( db_step(&q)==SQLITE_ROW ){
const char *zCmd = db_column_text(&q,0);
char *zCmd2 = hook_subst(zCmd, zAuxFilename);
int needOut = db_column_int(&q,1);
Blob out;
blob_init(&out,0,0);
if( needOut ) hook_changes(&out, zOrigRcvid, zNewRcvid);
if( bDryRun ){
fossil_print("%s\n", zCmd2);
if( needOut ){
|
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
);
while( db_step(&q)==SQLITE_ROW ){
char *zCmd;
FILE *f;
if( cnt==0 ){
hook_changes(&chng, zLastRcvid, 0);
}
zCmd = hook_subst(db_column_text(&q,0));
f = popen(zCmd, "w");
if( f ){
fwrite(blob_buffer(&chng),1,blob_size(&chng),f);
pclose(f);
}
fossil_free(zCmd);
cnt++;
}
db_finalize(&q);
db_set("hook-last-rcvid", zNewRcvid, 0);
blob_reset(&chng);
hook_backoffice_done:
db_commit_transaction();
return cnt;
}
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
|
);
while( db_step(&q)==SQLITE_ROW ){
char *zCmd;
FILE *f;
if( cnt==0 ){
hook_changes(&chng, zLastRcvid, 0);
}
zCmd = hook_subst(db_column_text(&q,0), 0);
f = popen(zCmd, "w");
if( f ){
fwrite(blob_buffer(&chng),1,blob_size(&chng),f);
pclose(f);
}
fossil_free(zCmd);
cnt++;
}
db_finalize(&q);
db_set("hook-last-rcvid", zNewRcvid, 0);
blob_reset(&chng);
hook_backoffice_done:
db_commit_transaction();
return cnt;
}
/*
** Run all hooks of type zType. Use zAuxFile as the auxiliary information
** file.
**
** If any hook returns non-zero, then stop running and return non-zero.
** Return zero only if all hooks return zero.
*/
int hook_run(const char *zType, const char *zAuxFile, int traceFlag){
Stmt q;
int rc = 0;
if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
return 0;
}
db_prepare(&q,
"SELECT json_extract(jx.value,'$.cmd') "
" FROM config, json_each(config.value) AS jx"
" WHERE config.name='hooks' AND json_valid(config.value)"
" AND json_extract(jx.value,'$.type')=%Q"
" ORDER BY json_extract(jx.value,'$.seq');",
zType
);
while( db_step(&q)==SQLITE_ROW ){
char *zCmd;
zCmd = hook_subst(db_column_text(&q,0), zAuxFile);
if( traceFlag ){
fossil_print("%s hook: %s\n", zType, zCmd);
}
rc = fossil_system(zCmd);
fossil_free(zCmd);
if( rc ){
break;
}
}
db_finalize(&q);
return rc;
}
|