Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch th1_fossiltag_cmd Excluding Merge-Ins
This is equivalent to a diff from 26c262cd03 to 413ebeb12e
2010-10-21
| ||
23:26 | TH1 fossiltag command for accessing tag values. Has two subcommands: get and list, which do what they sound like. Leaf check-in: 413ebeb12e user: bcsmith tags: th1_fossiltag_cmd | |
2010-10-11
| ||
13:43 | Allow events to be referenced using a prefix of their full event-id. check-in: f2025072b4 user: drh tags: trunk | |
2010-10-09
| ||
17:18 | Fix a potential segfault on "fossil pull". Ticket [71439c64b8d6af66f5e34]. check-in: 26c262cd03 user: drh tags: trunk | |
13:04 | Add a compile-time option to ignore the control file checksum (for a modest performance increase while parsing control files.) Enhance the test-parse-manifest command to facilitate performance studies. check-in: 712988286e user: drh tags: trunk | |
Changes to src/th_main.c.
231 231 } 232 232 if( g.thTrace ){ 233 233 Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc); 234 234 } 235 235 Th_SetResultInt(interp, rc); 236 236 return TH_OK; 237 237 } 238 + 239 +/* 240 +** 241 +** TH1 command: fossiltag list ?ARTIFACT-ID? 242 +** 243 +** Returns a list of tags on ARTIFACT-ID. Or, all tags, 244 +** if ARTIFACT-ID is not specified. Only uncancelled tags 245 +** are included in the result. 246 +** 247 +** Example: 248 +** <b>List of tags on thing:</b> 249 +** <th1> 250 +** puts [fossiltag list 2b4630f34] 251 +** </th1> 252 +*/ 253 +static int fossiltagListCmd( 254 + Th_Interp *interp, 255 + void *p, 256 + int argc, 257 + const char **argv, 258 + int *argl 259 +){ 260 + Stmt st; 261 + char *zTagList = 0; 262 + int nTagList = 0; 263 + if( argc==3 ){ 264 + db_prepare(&st, 265 + "SELECT tag.tagname FROM tag, tagxref " 266 + " WHERE tagxref.rid=%d " 267 + " AND tagxref.tagid=tag.tagid" 268 + " AND tagxref.tagtype>0 ", 269 + name_to_rid((char*)argv[2]) 270 + ); 271 + } 272 + else { 273 + db_prepare(&st, 274 + "SELECT DISTINCT tag.tagname FROM tag, tagxref " 275 + " WHERE " 276 + " tagxref.tagid=tag.tagid" 277 + " AND tagxref.tagtype>0 " 278 + ); 279 + } 280 + while( db_step(&st) == SQLITE_ROW ){ 281 + char *tagname = (char*)db_column_text(&st, 0); 282 + Th_ListAppend(interp, &zTagList, &nTagList, tagname, -1); 283 + 284 + } 285 + 286 + Th_SetResult(interp, zTagList, nTagList); 287 + Th_Free(interp, zTagList); 288 + db_finalize(&st); 289 + return TH_OK; 290 +} 291 + 292 +/* 293 +** 294 +** TH1 command: fossiltag get TAG-NAME ?ARTIFACT-ID? ?FALLBACK-VALUE? 295 +** 296 +** Returns the value of TAG-NAME on ARTIFACT-ID, or 297 +** one of the following: 298 +** if FALLBACK-VALUE provided and TAG-NAME not present, 299 +** then FALLBACK-VALUE is returned. 300 +** if FALLBACK-VALUE not provided, and TAG-NAME not present, 301 +** then 0 returned. 302 +** if TAG-NAME present, but has no value, then 1 is returned. 303 +** 304 +** Example: 305 +** <b>Check-in acceptance status:</b> 306 +** <th1> 307 +** set accept_out "" 308 +** if {[set out [fossiltag get "QA_acceptance" $check_in_id "<b>DID NOT PASS</b>"]]} { 309 +** set accept_out " * QA: ${out}" 310 +** } 311 +** if {[set out [fossiltag get "Unit_passed" $check_in_id "<b>DID NOT PASS UNIT TESTS</b>"]]} { 312 +** set accept_out "${accept_out}\n * Unit tests: ${out}" 313 +** } 314 +** if {[set out [fossiltag get "Signed_off_by" $check_in_id "<b>NOT SIGNED OFF</b>"]]} { 315 +** set accept_out "${accept_out}\n * Signed off by: ${out}" 316 +** } 317 +** puts [wiki $accept_out] 318 +** </th1> 319 +*/ 320 +static int fossiltagGetCmd( 321 + Th_Interp *interp, 322 + void *p, 323 + int argc, 324 + const char **argv, 325 + int *argl 326 +){ 327 + int rid = -1; 328 + char *zTagValue = 0; 329 + char *zDefault = 0; 330 + int nDefault = 0; 331 + db_open_local(); 332 + db_open_repository(0); 333 + if( argc<3 ){ 334 + return Th_WrongNumArgs(interp, "fossiltag get TAG-NAME ?ARTIFACT-ID? ?FALLBACK-TEXT?"); 335 + } 336 + /* if a fallback value was provided, place it in zDefault */ 337 + if( argc==5 ){ 338 + zDefault = (char*)argv[4]; 339 + nDefault = argl[4]; 340 + } 341 + /* if an artifact-id (name) is given.. */ 342 + if( argc>=4 && strlen((char*)argv[3])){ 343 + rid = 344 + db_int(0, 345 + "SELECT blob.rid " 346 + " FROM tag, tagxref, blob " 347 + "WHERE tag.tagname=%Q AND blob.rid=%d" 348 + " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " 349 + " AND blob.rid=tagxref.rid ", 350 + argv[2], name_to_rid((char*)argv[3]) 351 + ); 352 + 353 + if( g.thTrace ){ 354 + Th_Trace("[tagget] artifact-id: %s %d\n", argv[3], rid); 355 + } 356 + } 357 + else { /* if no artifact-id is given, we select the most recent commit 358 + containing TAG-NAME */ 359 + rid = 360 + db_int(0, 361 + "SELECT blob.rid " 362 + " FROM tag, tagxref, event, blob " 363 + "WHERE tag.tagname=%Q " 364 + " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " 365 + " AND event.objid=tagxref.rid " 366 + " AND blob.rid=event.objid " 367 + "ORDER BY event.mtime DESC ", 368 + argv[2] 369 + ); 370 + if( g.thTrace ){ 371 + Th_Trace("[tagget] artifact-rid: %d\n", rid); 372 + } 373 + } 374 + 375 + /* return 0 or the fallback value, since we couldn't 376 + find an artifact with TAG-NAME on it. */ 377 + if( rid==0 && argc==5 ){ 378 + if( g.thTrace ){ 379 + Th_Trace("[tagget] tag not on any artifact; returning default: %s\n", zDefault); 380 + } 381 + Th_SetResult(interp, zDefault, nDefault); 382 + return TH_OK; 383 + } 384 + else if( rid==0 && argc<5 ){ 385 + if( g.thTrace ){ 386 + Th_Trace("[tagget] tag not on any artifact; ret: 0\n"); 387 + } 388 + Th_SetResultInt(interp, 0); 389 + return TH_OK; 390 + } 391 + 392 + zTagValue = db_text(zDefault, 393 + "SELECT tagxref.value FROM tag, tagxref " 394 + " WHERE tag.tagname=%Q " 395 + " AND tagxref.tagid=tag.tagid " 396 + " AND tagxref.rid=%d ", 397 + argv[2], rid 398 + ); 399 + if( zTagValue && strlen(zTagValue)==0 ){ 400 + if( g.thTrace ){ 401 + Th_Trace("[tagget] tag has no value; ret: 1\n"); 402 + } 403 + Th_SetResultInt(interp, 1); 404 + free(zTagValue); 405 + } 406 + else { 407 + if( g.thTrace ){ 408 + Th_Trace("[tagget] returning tag value: %s\n", zTagValue); 409 + } 410 + Th_SetResult(interp, zTagValue, -1); 411 + free(zTagValue); 412 + } 413 + return TH_OK; 414 +} 415 + 416 +/* 417 +** TH1 command: fossiltag list|get ... 418 +** 419 +** Provide TH1 commands for read-only interation with tags on 420 +** any taggable artifact. The tags are always raw. 421 +** 422 +*/ 423 +static int fossiltagCmd( 424 + Th_Interp *interp, 425 + void *p, 426 + int argc, 427 + const char **argv, 428 + int *argl 429 +){ 430 + Th_SubCommand aSub[] = { 431 + { "list", fossiltagListCmd }, 432 + { "get", fossiltagGetCmd }, 433 + { 0, 0 } 434 + }; 435 + return Th_CallSubCommand(interp, p, argc, argv, argl, aSub); 436 +} 238 437 239 438 /* 240 439 ** TH1 command: combobox NAME TEXT-LIST NUMLINES 241 440 ** 242 441 ** Generate an HTML combobox. NAME is both the name of the 243 442 ** CGI parameter and the name of a variable that contains the 244 443 ** currently selected value. TEXT-LIST is a list of possible ................................................................................ 348 547 {"linecount", linecntCmd, 0}, 349 548 {"hascap", hascapCmd, 0}, 350 549 {"htmlize", htmlizeCmd, 0}, 351 550 {"date", dateCmd, 0}, 352 551 {"html", putsCmd, 0}, 353 552 {"puts", putsCmd, (void*)1}, 354 553 {"wiki", wikiCmd, 0}, 554 + {"fossiltag", fossiltagCmd, 0}, 355 555 }; 356 556 if( g.interp==0 ){ 357 557 int i; 358 558 g.interp = Th_CreateInterp(&vtab); 359 559 th_register_language(g.interp); /* Basic scripting commands. */ 360 560 for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){ 361 561 Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc, ................................................................................ 517 717 } 518 718 519 719 /* 520 720 ** COMMAND: test-th-render 521 721 */ 522 722 void test_th_render(void){ 523 723 Blob in; 724 + g.thTrace = find_option("th-trace", 0, 0)!=0; 725 + if( g.thTrace ){ 726 + blob_zero(&g.thLog); 727 + } 524 728 if( g.argc<3 ){ 525 729 usage("FILE"); 526 730 } 527 731 blob_zero(&in); 528 - blob_read_from_file(&in, g.argv[2]); 732 + if( g.thTrace ){ 733 + blob_read_from_file(&in, g.argv[3]); 734 + } 735 + else{ 736 + blob_read_from_file(&in, g.argv[2]); 737 + } 529 738 Th_Render(blob_str(&in)); 739 + if( g.thTrace ){ 740 + fossil_print("%s", blob_materialize(&g.thLog)); 741 + } 530 742 }