Fossil SCM
Initial version of manifest-to-json rendering. All card types are implemented but not all have been tested.
Commit
e3e8fa351b9649b425e92bb96364d7f0903173767b83a31eea4f54ac364b77fa
Parent
479803600c4a261…
1 file changed
+29
-7
+29
-7
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -2912,30 +2912,46 @@ | ||
| 2912 | 2912 | rid = name_to_rid(g.argv[2]); |
| 2913 | 2913 | content_get(rid, &content); |
| 2914 | 2914 | manifest_crosslink(rid, &content, MC_NONE); |
| 2915 | 2915 | } |
| 2916 | 2916 | |
| 2917 | +/* | |
| 2918 | +** Creates a JSON representation of p, appending it to pOut. | |
| 2919 | +*/ | |
| 2917 | 2920 | void artifact_to_json(Manifest *p, Blob *pOut){ |
| 2918 | 2921 | char * zTmp; |
| 2919 | - blob_reset(pOut); | |
| 2920 | 2922 | blob_append_literal(pOut, "{"); |
| 2921 | - blob_appendf(pOut, "\"rid\": %d, ", p->rid); | |
| 2923 | + blob_appendf(pOut, "\"rid\": %d", p->rid); | |
| 2922 | 2924 | zTmp = rid_to_uuid(p->rid); |
| 2923 | - blob_appendf(pOut, "\"uuid\": %!j", zTmp); | |
| 2925 | + blob_appendf(pOut, ", \"uuid\": %!j", zTmp); | |
| 2924 | 2926 | fossil_free(zTmp); |
| 2927 | +#define CARD_FMT(LETTER, FMT, VAL) \ | |
| 2928 | + blob_appendf(pOut, ",\"" #LETTER "\": " #FMT, VAL) | |
| 2929 | +#define CARD_STR(LETTER, VAL) \ | |
| 2930 | + assert( VAL ); CARD_FMT(LETTER, %!j, VAL) | |
| 2931 | +#define CARD_STR2(LETTER, VAL) \ | |
| 2932 | + if( VAL ) { CARD_FMT(LETTER, %!j, VAL); } | |
| 2933 | + | |
| 2934 | + CARD_STR2(B, p->zBaseline); | |
| 2935 | + CARD_STR2(C, p->zComment); | |
| 2936 | + CARD_FMT(D, %f, p->rDate); | |
| 2937 | + CARD_STR2(W, p->zWiki); | |
| 2938 | + CARD_STR2(R, p->zRepoCksum); | |
| 2925 | 2939 | blob_append_literal(pOut, "}"); |
| 2940 | +#undef CARD_STR | |
| 2941 | +#undef CARD_STR2 | |
| 2942 | +#undef CARD_FMT | |
| 2926 | 2943 | } |
| 2927 | 2944 | |
| 2928 | 2945 | /* |
| 2929 | 2946 | ** Convenience wrapper around artifact_to_json() which accepts any |
| 2930 | 2947 | ** artifact name which is legal for symbolic_name_to_rid(). On success |
| 2931 | 2948 | ** it returns the rid of the artifact. Returns 0 if no such artifact |
| 2932 | 2949 | ** exists and a negative value if the name is ambiguous. |
| 2933 | 2950 | ** |
| 2934 | -** If it returns a valid rid, pOut will be cleared before emitting the | |
| 2935 | -** JSON to it. | |
| 2936 | -** | |
| 2951 | +** pOut is not cleared before rendering, so the caller needs to do | |
| 2952 | +** that if it's important for their use case. | |
| 2937 | 2953 | */ |
| 2938 | 2954 | int artifact_to_json_by_name(const char *zName, Blob *pOut){ |
| 2939 | 2955 | int rid; |
| 2940 | 2956 | |
| 2941 | 2957 | rid = symbolic_name_to_rid(zName, 0); |
| @@ -2958,18 +2974,21 @@ | ||
| 2958 | 2974 | void test_manifest_to_json(void){ |
| 2959 | 2975 | int i; |
| 2960 | 2976 | Blob b = empty_blob; |
| 2961 | 2977 | Stmt q; |
| 2962 | 2978 | const int bPretty = find_option("pretty",0,0)!=0; |
| 2979 | + int nErr = 0; | |
| 2963 | 2980 | |
| 2964 | 2981 | db_find_and_open_repository(0,0); |
| 2965 | 2982 | db_prepare(&q, "select json_pretty(:json)"); |
| 2966 | 2983 | for( i=2; i<g.argc; ++i ){ |
| 2967 | 2984 | char const *zName = g.argv[i]; |
| 2968 | 2985 | const int rc = artifact_to_json_by_name(zName, &b); |
| 2969 | 2986 | if( rc<=0 ){ |
| 2970 | - fossil_warning("Error reading artifact %Q\n", zName); | |
| 2987 | + ++nErr; | |
| 2988 | + fossil_warning("Error reading artifact %Q", zName); | |
| 2989 | + continue; | |
| 2971 | 2990 | }else if( bPretty ){ |
| 2972 | 2991 | db_bind_blob(&q, ":json", &b); |
| 2973 | 2992 | b.nUsed = 0; |
| 2974 | 2993 | db_step(&q); |
| 2975 | 2994 | db_column_blob(&q, 0, &b); |
| @@ -2977,6 +2996,9 @@ | ||
| 2977 | 2996 | } |
| 2978 | 2997 | fossil_print("%b\n", &b); |
| 2979 | 2998 | blob_reset(&b); |
| 2980 | 2999 | } |
| 2981 | 3000 | db_finalize(&q); |
| 3001 | + if( nErr ){ | |
| 3002 | + fossil_warning("Error count: %d", nErr); | |
| 3003 | + } | |
| 2982 | 3004 | } |
| 2983 | 3005 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -2912,30 +2912,46 @@ | |
| 2912 | rid = name_to_rid(g.argv[2]); |
| 2913 | content_get(rid, &content); |
| 2914 | manifest_crosslink(rid, &content, MC_NONE); |
| 2915 | } |
| 2916 | |
| 2917 | void artifact_to_json(Manifest *p, Blob *pOut){ |
| 2918 | char * zTmp; |
| 2919 | blob_reset(pOut); |
| 2920 | blob_append_literal(pOut, "{"); |
| 2921 | blob_appendf(pOut, "\"rid\": %d, ", p->rid); |
| 2922 | zTmp = rid_to_uuid(p->rid); |
| 2923 | blob_appendf(pOut, "\"uuid\": %!j", zTmp); |
| 2924 | fossil_free(zTmp); |
| 2925 | blob_append_literal(pOut, "}"); |
| 2926 | } |
| 2927 | |
| 2928 | /* |
| 2929 | ** Convenience wrapper around artifact_to_json() which accepts any |
| 2930 | ** artifact name which is legal for symbolic_name_to_rid(). On success |
| 2931 | ** it returns the rid of the artifact. Returns 0 if no such artifact |
| 2932 | ** exists and a negative value if the name is ambiguous. |
| 2933 | ** |
| 2934 | ** If it returns a valid rid, pOut will be cleared before emitting the |
| 2935 | ** JSON to it. |
| 2936 | ** |
| 2937 | */ |
| 2938 | int artifact_to_json_by_name(const char *zName, Blob *pOut){ |
| 2939 | int rid; |
| 2940 | |
| 2941 | rid = symbolic_name_to_rid(zName, 0); |
| @@ -2958,18 +2974,21 @@ | |
| 2958 | void test_manifest_to_json(void){ |
| 2959 | int i; |
| 2960 | Blob b = empty_blob; |
| 2961 | Stmt q; |
| 2962 | const int bPretty = find_option("pretty",0,0)!=0; |
| 2963 | |
| 2964 | db_find_and_open_repository(0,0); |
| 2965 | db_prepare(&q, "select json_pretty(:json)"); |
| 2966 | for( i=2; i<g.argc; ++i ){ |
| 2967 | char const *zName = g.argv[i]; |
| 2968 | const int rc = artifact_to_json_by_name(zName, &b); |
| 2969 | if( rc<=0 ){ |
| 2970 | fossil_warning("Error reading artifact %Q\n", zName); |
| 2971 | }else if( bPretty ){ |
| 2972 | db_bind_blob(&q, ":json", &b); |
| 2973 | b.nUsed = 0; |
| 2974 | db_step(&q); |
| 2975 | db_column_blob(&q, 0, &b); |
| @@ -2977,6 +2996,9 @@ | |
| 2977 | } |
| 2978 | fossil_print("%b\n", &b); |
| 2979 | blob_reset(&b); |
| 2980 | } |
| 2981 | db_finalize(&q); |
| 2982 | } |
| 2983 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -2912,30 +2912,46 @@ | |
| 2912 | rid = name_to_rid(g.argv[2]); |
| 2913 | content_get(rid, &content); |
| 2914 | manifest_crosslink(rid, &content, MC_NONE); |
| 2915 | } |
| 2916 | |
| 2917 | /* |
| 2918 | ** Creates a JSON representation of p, appending it to pOut. |
| 2919 | */ |
| 2920 | void artifact_to_json(Manifest *p, Blob *pOut){ |
| 2921 | char * zTmp; |
| 2922 | blob_append_literal(pOut, "{"); |
| 2923 | blob_appendf(pOut, "\"rid\": %d", p->rid); |
| 2924 | zTmp = rid_to_uuid(p->rid); |
| 2925 | blob_appendf(pOut, ", \"uuid\": %!j", zTmp); |
| 2926 | fossil_free(zTmp); |
| 2927 | #define CARD_FMT(LETTER, FMT, VAL) \ |
| 2928 | blob_appendf(pOut, ",\"" #LETTER "\": " #FMT, VAL) |
| 2929 | #define CARD_STR(LETTER, VAL) \ |
| 2930 | assert( VAL ); CARD_FMT(LETTER, %!j, VAL) |
| 2931 | #define CARD_STR2(LETTER, VAL) \ |
| 2932 | if( VAL ) { CARD_FMT(LETTER, %!j, VAL); } |
| 2933 | |
| 2934 | CARD_STR2(B, p->zBaseline); |
| 2935 | CARD_STR2(C, p->zComment); |
| 2936 | CARD_FMT(D, %f, p->rDate); |
| 2937 | CARD_STR2(W, p->zWiki); |
| 2938 | CARD_STR2(R, p->zRepoCksum); |
| 2939 | blob_append_literal(pOut, "}"); |
| 2940 | #undef CARD_STR |
| 2941 | #undef CARD_STR2 |
| 2942 | #undef CARD_FMT |
| 2943 | } |
| 2944 | |
| 2945 | /* |
| 2946 | ** Convenience wrapper around artifact_to_json() which accepts any |
| 2947 | ** artifact name which is legal for symbolic_name_to_rid(). On success |
| 2948 | ** it returns the rid of the artifact. Returns 0 if no such artifact |
| 2949 | ** exists and a negative value if the name is ambiguous. |
| 2950 | ** |
| 2951 | ** pOut is not cleared before rendering, so the caller needs to do |
| 2952 | ** that if it's important for their use case. |
| 2953 | */ |
| 2954 | int artifact_to_json_by_name(const char *zName, Blob *pOut){ |
| 2955 | int rid; |
| 2956 | |
| 2957 | rid = symbolic_name_to_rid(zName, 0); |
| @@ -2958,18 +2974,21 @@ | |
| 2974 | void test_manifest_to_json(void){ |
| 2975 | int i; |
| 2976 | Blob b = empty_blob; |
| 2977 | Stmt q; |
| 2978 | const int bPretty = find_option("pretty",0,0)!=0; |
| 2979 | int nErr = 0; |
| 2980 | |
| 2981 | db_find_and_open_repository(0,0); |
| 2982 | db_prepare(&q, "select json_pretty(:json)"); |
| 2983 | for( i=2; i<g.argc; ++i ){ |
| 2984 | char const *zName = g.argv[i]; |
| 2985 | const int rc = artifact_to_json_by_name(zName, &b); |
| 2986 | if( rc<=0 ){ |
| 2987 | ++nErr; |
| 2988 | fossil_warning("Error reading artifact %Q", zName); |
| 2989 | continue; |
| 2990 | }else if( bPretty ){ |
| 2991 | db_bind_blob(&q, ":json", &b); |
| 2992 | b.nUsed = 0; |
| 2993 | db_step(&q); |
| 2994 | db_column_blob(&q, 0, &b); |
| @@ -2977,6 +2996,9 @@ | |
| 2996 | } |
| 2997 | fossil_print("%b\n", &b); |
| 2998 | blob_reset(&b); |
| 2999 | } |
| 3000 | db_finalize(&q); |
| 3001 | if( nErr ){ |
| 3002 | fossil_warning("Error count: %d", nErr); |
| 3003 | } |
| 3004 | } |
| 3005 |