Fossil SCM

Add -p short-form flag of --pretty to test-artifact-to-json. Restore the part of [8af0d05c66e6] which removes extraneous whitespace from artifact_to_json().

stephan 2025-03-25 17:29 trunk
Commit 3e0d7b0613789a70daa6995cd0dfa861c7aaee933221b67a9d6df2c2b290e7aa
2 files changed +25 -5 +10 -10
+25 -5
--- src/content.c
+++ src/content.c
@@ -325,25 +325,45 @@
325325
** standard output, or if the optional second argument is given, in
326326
** the named output file.
327327
**
328328
** Options:
329329
** -R|--repository REPO Extract artifacts from repository REPO
330
+** -j|--json Emit the result as JSON
331
+** -p|--pretty Pretty-print JSON
330332
**
331333
** See also: [[finfo]]
332334
*/
333335
void artifact_cmd(void){
334336
int rid;
335
- Blob content;
337
+ Blob content = empty_blob;
336338
const char *zFile;
339
+ const int bJson = find_option("json", "j", 0)!=0;
340
+ const int bPretty = find_option("pretty", "p", 0)!=0;
341
+
342
+ verify_all_options();
337343
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
338
- if( g.argc!=4 && g.argc!=3 ) usage("ARTIFACT-ID ?FILENAME? ?OPTIONS?");
344
+ if( g.argc!=4 && g.argc!=3 ){
345
+ usage("?-json? ARTIFACT-ID ?FILENAME? ?OPTIONS?");
346
+ }
339347
zFile = g.argc==4 ? g.argv[3] : "-";
340348
rid = name_to_rid(g.argv[2]);
341
- if( rid==0 ){
342
- fossil_fatal("%s",g.zErrMsg);
349
+ assert( rid>0 && "name_to_rid() fails fatally on resolution error" );
350
+ if( bJson || bPretty ){
351
+ artifact_to_json_by_rid(rid, &content);
352
+ if( bPretty ){
353
+ Stmt q;
354
+ db_prepare(&q, "select json_pretty(:json)");
355
+ db_bind_blob(&q, ":json", &content);
356
+ db_step(&q);
357
+ content.nUsed = 0;
358
+ db_column_blob(&q, 0, &content);
359
+ db_finalize(&q);
360
+ }
361
+ blob_append_char(&content, '\n');
362
+ }else{
363
+ content_get(rid, &content);
343364
}
344
- content_get(rid, &content);
345365
blob_write_to_file(&content, zFile);
346366
}
347367
348368
/*
349369
** COMMAND: test-content-rawget
350370
--- src/content.c
+++ src/content.c
@@ -325,25 +325,45 @@
325 ** standard output, or if the optional second argument is given, in
326 ** the named output file.
327 **
328 ** Options:
329 ** -R|--repository REPO Extract artifacts from repository REPO
 
 
330 **
331 ** See also: [[finfo]]
332 */
333 void artifact_cmd(void){
334 int rid;
335 Blob content;
336 const char *zFile;
 
 
 
 
337 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
338 if( g.argc!=4 && g.argc!=3 ) usage("ARTIFACT-ID ?FILENAME? ?OPTIONS?");
 
 
339 zFile = g.argc==4 ? g.argv[3] : "-";
340 rid = name_to_rid(g.argv[2]);
341 if( rid==0 ){
342 fossil_fatal("%s",g.zErrMsg);
 
 
 
 
 
 
 
 
 
 
 
 
 
343 }
344 content_get(rid, &content);
345 blob_write_to_file(&content, zFile);
346 }
347
348 /*
349 ** COMMAND: test-content-rawget
350
--- src/content.c
+++ src/content.c
@@ -325,25 +325,45 @@
325 ** standard output, or if the optional second argument is given, in
326 ** the named output file.
327 **
328 ** Options:
329 ** -R|--repository REPO Extract artifacts from repository REPO
330 ** -j|--json Emit the result as JSON
331 ** -p|--pretty Pretty-print JSON
332 **
333 ** See also: [[finfo]]
334 */
335 void artifact_cmd(void){
336 int rid;
337 Blob content = empty_blob;
338 const char *zFile;
339 const int bJson = find_option("json", "j", 0)!=0;
340 const int bPretty = find_option("pretty", "p", 0)!=0;
341
342 verify_all_options();
343 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
344 if( g.argc!=4 && g.argc!=3 ){
345 usage("?-json? ARTIFACT-ID ?FILENAME? ?OPTIONS?");
346 }
347 zFile = g.argc==4 ? g.argv[3] : "-";
348 rid = name_to_rid(g.argv[2]);
349 assert( rid>0 && "name_to_rid() fails fatally on resolution error" );
350 if( bJson || bPretty ){
351 artifact_to_json_by_rid(rid, &content);
352 if( bPretty ){
353 Stmt q;
354 db_prepare(&q, "select json_pretty(:json)");
355 db_bind_blob(&q, ":json", &content);
356 db_step(&q);
357 content.nUsed = 0;
358 db_column_blob(&q, 0, &content);
359 db_finalize(&q);
360 }
361 blob_append_char(&content, '\n');
362 }else{
363 content_get(rid, &content);
364 }
 
365 blob_write_to_file(&content, zFile);
366 }
367
368 /*
369 ** COMMAND: test-content-rawget
370
+10 -10
--- src/manifest.c
+++ src/manifest.c
@@ -2948,26 +2948,26 @@
29482948
*/
29492949
void artifact_to_json(Manifest const *p, Blob *b){
29502950
int i;
29512951
29522952
blob_append_literal(b, "{");
2953
- blob_appendf(b, "\"uuid\": \"%z\"", rid_to_uuid(p->rid));
2953
+ blob_appendf(b, "\"uuid\":\"%z\"", rid_to_uuid(p->rid));
29542954
/*blob_appendf(b, ", \"rid\": %d", p->rid); not portable across repos*/
2955
- blob_appendf(b, ", \"type\": %!j", artifact_type_to_name(p->type));
2955
+ blob_appendf(b, ",\"type\":%!j", artifact_type_to_name(p->type));
29562956
#define ISA(TYPE) if( p->type==TYPE )
29572957
#define CARD_LETTER(LETTER) \
2958
- blob_append_literal(b, ",\"" #LETTER "\": ")
2958
+ blob_append_literal(b, ",\"" #LETTER "\":")
29592959
#define CARD_STR(LETTER, VAL) \
29602960
assert( VAL ); CARD_LETTER(LETTER); blob_appendf(b, "%!j", VAL)
29612961
#define CARD_STR2(LETTER, VAL) \
29622962
if( VAL ) { CARD_STR(LETTER, VAL); } (void)0
29632963
#define STR_OR_NULL(VAL) \
29642964
if( VAL ) blob_appendf(b, "%!j", VAL); \
29652965
else blob_append(b, "null", 4)
29662966
#define KVP_STR(ADDCOMMA, KEY,VAL) \
29672967
if(ADDCOMMA) blob_append_char(b, ','); \
2968
- blob_appendf(b, "%!j: ", #KEY); \
2968
+ blob_appendf(b, "%!j:", #KEY); \
29692969
STR_OR_NULL(VAL)
29702970
29712971
ISA( CFTYPE_ATTACHMENT ){
29722972
CARD_LETTER(A);
29732973
blob_append_char(b, '{');
@@ -2978,11 +2978,11 @@
29782978
}
29792979
CARD_STR2(B, p->zBaseline);
29802980
CARD_STR2(C, p->zComment);
29812981
CARD_LETTER(D); blob_appendf(b, "%f", p->rDate);
29822982
ISA( CFTYPE_EVENT ){
2983
- blob_appendf(b, ", \"E\": {\"time\": %f, \"id\": %!j}",
2983
+ blob_appendf(b, ", \"E\":{\"time\":%f,\"id\":%!j}",
29842984
p->rEventDate, p->zEventId);
29852985
}
29862986
ISA( CFTYPE_MANIFEST ){
29872987
CARD_LETTER(F);
29882988
blob_append_char(b, '[');
@@ -3014,11 +3014,11 @@
30143014
const char * zName = p->aField[i].zName;
30153015
if( i>0 ) blob_append_char(b, ',');
30163016
blob_append_char(b, '{');
30173017
KVP_STR(0, name, '+'==*zName ? &zName[1] : zName);
30183018
KVP_STR(1, value, p->aField[i].zValue);
3019
- blob_appendf(b, ", \"append\": %s", '+'==*zName ? "true" : "false");
3019
+ blob_appendf(b, ",\"append\":%s", '+'==*zName ? "true" : "false");
30203020
blob_append_char(b, '}');
30213021
}
30223022
blob_append_char(b, ']');
30233023
}
30243024
CARD_STR2(K, p->zTicketUuid);
@@ -3048,11 +3048,11 @@
30483048
CARD_LETTER(Q);
30493049
blob_append_char(b, '[');
30503050
for( i = 0; i < p->nCherrypick; ++i ){
30513051
if( i>0 ) blob_append_char(b, ',');
30523052
blob_append_char(b, '{');
3053
- blob_appendf(b, "\"type\": \"%c\"", p->aCherrypick[i].zCPTarget[0]);
3053
+ blob_appendf(b, "\"type\":\"%c\"", p->aCherrypick[i].zCPTarget[0]);
30543054
KVP_STR(1, target, &p->aCherrypick[i].zCPTarget[1]);
30553055
KVP_STR(1, base, p->aCherrypick[i].zCPBase);
30563056
blob_append_char(b, '}');
30573057
}
30583058
blob_append_char(b, ']');
@@ -3063,11 +3063,11 @@
30633063
blob_append_char(b, '[');
30643064
for( int i = 0; i < p->nTag; ++i ){
30653065
const char *zName = p->aTag[i].zName;
30663066
if( i>0 ) blob_append_char(b, ',');
30673067
blob_append_char(b, '{');
3068
- blob_appendf(b, "\"type\": \"%c\"", *zName);
3068
+ blob_appendf(b, "\"type\":\"%c\"", *zName);
30693069
KVP_STR(1, name, &zName[1]);
30703070
KVP_STR(1, target, p->aTag[i].zUuid ? p->aTag[i].zUuid : "*")
30713071
/* We could arguably resolve the "*" as null or p's uuid. */;
30723072
KVP_STR(1, value, p->aTag[i].zValue);
30733073
blob_append_char(b, '}');
@@ -3170,19 +3170,19 @@
31703170
31713171
31723172
/*
31733173
** COMMAND: test-artifact-to-json
31743174
**
3175
-** Usage: %fossil test-artifact-to-json ?-pretty? symbolic-name [...names]
3175
+** Usage: %fossil test-artifact-to-json ?-pretty|-p? symbolic-name [...names]
31763176
**
31773177
** Tests the artifact_to_json() and artifact_to_json_by_name() APIs.
31783178
*/
31793179
void test_manifest_to_json(void){
31803180
int i;
31813181
Blob b = empty_blob;
31823182
Stmt q;
3183
- const int bPretty = find_option("pretty",0,0)!=0;
3183
+ const int bPretty = find_option("pretty","p",0)!=0;
31843184
int nErr = 0;
31853185
31863186
db_find_and_open_repository(0,0);
31873187
db_prepare(&q, "select json_pretty(:json)");
31883188
for( i=2; i<g.argc; ++i ){
31893189
--- src/manifest.c
+++ src/manifest.c
@@ -2948,26 +2948,26 @@
2948 */
2949 void artifact_to_json(Manifest const *p, Blob *b){
2950 int i;
2951
2952 blob_append_literal(b, "{");
2953 blob_appendf(b, "\"uuid\": \"%z\"", rid_to_uuid(p->rid));
2954 /*blob_appendf(b, ", \"rid\": %d", p->rid); not portable across repos*/
2955 blob_appendf(b, ", \"type\": %!j", artifact_type_to_name(p->type));
2956 #define ISA(TYPE) if( p->type==TYPE )
2957 #define CARD_LETTER(LETTER) \
2958 blob_append_literal(b, ",\"" #LETTER "\": ")
2959 #define CARD_STR(LETTER, VAL) \
2960 assert( VAL ); CARD_LETTER(LETTER); blob_appendf(b, "%!j", VAL)
2961 #define CARD_STR2(LETTER, VAL) \
2962 if( VAL ) { CARD_STR(LETTER, VAL); } (void)0
2963 #define STR_OR_NULL(VAL) \
2964 if( VAL ) blob_appendf(b, "%!j", VAL); \
2965 else blob_append(b, "null", 4)
2966 #define KVP_STR(ADDCOMMA, KEY,VAL) \
2967 if(ADDCOMMA) blob_append_char(b, ','); \
2968 blob_appendf(b, "%!j: ", #KEY); \
2969 STR_OR_NULL(VAL)
2970
2971 ISA( CFTYPE_ATTACHMENT ){
2972 CARD_LETTER(A);
2973 blob_append_char(b, '{');
@@ -2978,11 +2978,11 @@
2978 }
2979 CARD_STR2(B, p->zBaseline);
2980 CARD_STR2(C, p->zComment);
2981 CARD_LETTER(D); blob_appendf(b, "%f", p->rDate);
2982 ISA( CFTYPE_EVENT ){
2983 blob_appendf(b, ", \"E\": {\"time\": %f, \"id\": %!j}",
2984 p->rEventDate, p->zEventId);
2985 }
2986 ISA( CFTYPE_MANIFEST ){
2987 CARD_LETTER(F);
2988 blob_append_char(b, '[');
@@ -3014,11 +3014,11 @@
3014 const char * zName = p->aField[i].zName;
3015 if( i>0 ) blob_append_char(b, ',');
3016 blob_append_char(b, '{');
3017 KVP_STR(0, name, '+'==*zName ? &zName[1] : zName);
3018 KVP_STR(1, value, p->aField[i].zValue);
3019 blob_appendf(b, ", \"append\": %s", '+'==*zName ? "true" : "false");
3020 blob_append_char(b, '}');
3021 }
3022 blob_append_char(b, ']');
3023 }
3024 CARD_STR2(K, p->zTicketUuid);
@@ -3048,11 +3048,11 @@
3048 CARD_LETTER(Q);
3049 blob_append_char(b, '[');
3050 for( i = 0; i < p->nCherrypick; ++i ){
3051 if( i>0 ) blob_append_char(b, ',');
3052 blob_append_char(b, '{');
3053 blob_appendf(b, "\"type\": \"%c\"", p->aCherrypick[i].zCPTarget[0]);
3054 KVP_STR(1, target, &p->aCherrypick[i].zCPTarget[1]);
3055 KVP_STR(1, base, p->aCherrypick[i].zCPBase);
3056 blob_append_char(b, '}');
3057 }
3058 blob_append_char(b, ']');
@@ -3063,11 +3063,11 @@
3063 blob_append_char(b, '[');
3064 for( int i = 0; i < p->nTag; ++i ){
3065 const char *zName = p->aTag[i].zName;
3066 if( i>0 ) blob_append_char(b, ',');
3067 blob_append_char(b, '{');
3068 blob_appendf(b, "\"type\": \"%c\"", *zName);
3069 KVP_STR(1, name, &zName[1]);
3070 KVP_STR(1, target, p->aTag[i].zUuid ? p->aTag[i].zUuid : "*")
3071 /* We could arguably resolve the "*" as null or p's uuid. */;
3072 KVP_STR(1, value, p->aTag[i].zValue);
3073 blob_append_char(b, '}');
@@ -3170,19 +3170,19 @@
3170
3171
3172 /*
3173 ** COMMAND: test-artifact-to-json
3174 **
3175 ** Usage: %fossil test-artifact-to-json ?-pretty? symbolic-name [...names]
3176 **
3177 ** Tests the artifact_to_json() and artifact_to_json_by_name() APIs.
3178 */
3179 void test_manifest_to_json(void){
3180 int i;
3181 Blob b = empty_blob;
3182 Stmt q;
3183 const int bPretty = find_option("pretty",0,0)!=0;
3184 int nErr = 0;
3185
3186 db_find_and_open_repository(0,0);
3187 db_prepare(&q, "select json_pretty(:json)");
3188 for( i=2; i<g.argc; ++i ){
3189
--- src/manifest.c
+++ src/manifest.c
@@ -2948,26 +2948,26 @@
2948 */
2949 void artifact_to_json(Manifest const *p, Blob *b){
2950 int i;
2951
2952 blob_append_literal(b, "{");
2953 blob_appendf(b, "\"uuid\":\"%z\"", rid_to_uuid(p->rid));
2954 /*blob_appendf(b, ", \"rid\": %d", p->rid); not portable across repos*/
2955 blob_appendf(b, ",\"type\":%!j", artifact_type_to_name(p->type));
2956 #define ISA(TYPE) if( p->type==TYPE )
2957 #define CARD_LETTER(LETTER) \
2958 blob_append_literal(b, ",\"" #LETTER "\":")
2959 #define CARD_STR(LETTER, VAL) \
2960 assert( VAL ); CARD_LETTER(LETTER); blob_appendf(b, "%!j", VAL)
2961 #define CARD_STR2(LETTER, VAL) \
2962 if( VAL ) { CARD_STR(LETTER, VAL); } (void)0
2963 #define STR_OR_NULL(VAL) \
2964 if( VAL ) blob_appendf(b, "%!j", VAL); \
2965 else blob_append(b, "null", 4)
2966 #define KVP_STR(ADDCOMMA, KEY,VAL) \
2967 if(ADDCOMMA) blob_append_char(b, ','); \
2968 blob_appendf(b, "%!j:", #KEY); \
2969 STR_OR_NULL(VAL)
2970
2971 ISA( CFTYPE_ATTACHMENT ){
2972 CARD_LETTER(A);
2973 blob_append_char(b, '{');
@@ -2978,11 +2978,11 @@
2978 }
2979 CARD_STR2(B, p->zBaseline);
2980 CARD_STR2(C, p->zComment);
2981 CARD_LETTER(D); blob_appendf(b, "%f", p->rDate);
2982 ISA( CFTYPE_EVENT ){
2983 blob_appendf(b, ", \"E\":{\"time\":%f,\"id\":%!j}",
2984 p->rEventDate, p->zEventId);
2985 }
2986 ISA( CFTYPE_MANIFEST ){
2987 CARD_LETTER(F);
2988 blob_append_char(b, '[');
@@ -3014,11 +3014,11 @@
3014 const char * zName = p->aField[i].zName;
3015 if( i>0 ) blob_append_char(b, ',');
3016 blob_append_char(b, '{');
3017 KVP_STR(0, name, '+'==*zName ? &zName[1] : zName);
3018 KVP_STR(1, value, p->aField[i].zValue);
3019 blob_appendf(b, ",\"append\":%s", '+'==*zName ? "true" : "false");
3020 blob_append_char(b, '}');
3021 }
3022 blob_append_char(b, ']');
3023 }
3024 CARD_STR2(K, p->zTicketUuid);
@@ -3048,11 +3048,11 @@
3048 CARD_LETTER(Q);
3049 blob_append_char(b, '[');
3050 for( i = 0; i < p->nCherrypick; ++i ){
3051 if( i>0 ) blob_append_char(b, ',');
3052 blob_append_char(b, '{');
3053 blob_appendf(b, "\"type\":\"%c\"", p->aCherrypick[i].zCPTarget[0]);
3054 KVP_STR(1, target, &p->aCherrypick[i].zCPTarget[1]);
3055 KVP_STR(1, base, p->aCherrypick[i].zCPBase);
3056 blob_append_char(b, '}');
3057 }
3058 blob_append_char(b, ']');
@@ -3063,11 +3063,11 @@
3063 blob_append_char(b, '[');
3064 for( int i = 0; i < p->nTag; ++i ){
3065 const char *zName = p->aTag[i].zName;
3066 if( i>0 ) blob_append_char(b, ',');
3067 blob_append_char(b, '{');
3068 blob_appendf(b, "\"type\":\"%c\"", *zName);
3069 KVP_STR(1, name, &zName[1]);
3070 KVP_STR(1, target, p->aTag[i].zUuid ? p->aTag[i].zUuid : "*")
3071 /* We could arguably resolve the "*" as null or p's uuid. */;
3072 KVP_STR(1, value, p->aTag[i].zValue);
3073 blob_append_char(b, '}');
@@ -3170,19 +3170,19 @@
3170
3171
3172 /*
3173 ** COMMAND: test-artifact-to-json
3174 **
3175 ** Usage: %fossil test-artifact-to-json ?-pretty|-p? symbolic-name [...names]
3176 **
3177 ** Tests the artifact_to_json() and artifact_to_json_by_name() APIs.
3178 */
3179 void test_manifest_to_json(void){
3180 int i;
3181 Blob b = empty_blob;
3182 Stmt q;
3183 const int bPretty = find_option("pretty","p",0)!=0;
3184 int nErr = 0;
3185
3186 db_find_and_open_repository(0,0);
3187 db_prepare(&q, "select json_pretty(:json)");
3188 for( i=2; i<g.argc; ++i ){
3189

Keyboard Shortcuts

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