Fossil SCM
implemented add/set ticket commands
Commit
9d3b9d653a11eaaecec0409e88de3b65e6655b95
Parent
092d7630280b66a…
1 file changed
+103
-8
+103
-8
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -848,11 +848,11 @@ | ||
| 848 | 848 | ** If TICKETFILTER is given on the commandline, the query is |
| 849 | 849 | ** limited with a new WHERE-condition. |
| 850 | 850 | ** example: Report lists a column # with the uuid |
| 851 | 851 | ** TICKETFILTER= [#]='uuuuuuuuu' |
| 852 | 852 | ** |
| 853 | -** %fossil ticket set FIELD VALUE ?FIELD VALUE ... ? TICKETUUID | |
| 853 | +** %fossil ticket set TICKETUUID FIELD VALUE ?FIELD VALUE ... ? | |
| 854 | 854 | ** |
| 855 | 855 | ** change ticket identified by TICKETUUID and set the value of |
| 856 | 856 | ** field FIELD to VALUE. Valid field descriptions are: |
| 857 | 857 | ** status, type, severity, priority, resolution, |
| 858 | 858 | ** foundin, private_contact, resolution, title or comment |
| @@ -867,35 +867,130 @@ | ||
| 867 | 867 | ** |
| 868 | 868 | */ |
| 869 | 869 | void ticket_cmd(void){ |
| 870 | 870 | int n; |
| 871 | 871 | |
| 872 | + db_must_be_within_tree(); | |
| 872 | 873 | db_find_and_open_repository(1); |
| 873 | 874 | |
| 875 | + user_select(); | |
| 876 | + /* | |
| 877 | + ** Check that the user exists. | |
| 878 | + */ | |
| 879 | + if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){ | |
| 880 | + fossil_fatal("no such user: %s", g.zLogin); | |
| 881 | + } | |
| 882 | +fprintf(stdout,"%s\n",g.zLogin); | |
| 883 | + | |
| 874 | 884 | if( g.argc<3 ){ |
| 875 | 885 | usage("add|set|show"); |
| 876 | 886 | }else{ |
| 877 | 887 | n = strlen(g.argv[2]); |
| 878 | - if( strncmp(g.argv[2],"show",n)==0 ){ | |
| 888 | + if( n==1 && g.argv[2][0]=='s' ){ | |
| 889 | + usage("ticket show|set|add"); | |
| 890 | + }else if( strncmp(g.argv[2],"show",n)==0 ){ | |
| 879 | 891 | if( g.argc==3 ){ |
| 880 | 892 | usage("ticket show REPORTNR"); |
| 881 | 893 | }else{ |
| 882 | 894 | int rn; |
| 883 | 895 | const char *zSep = 0; |
| 884 | - const char *zFilterUuid = 0; | |
| 896 | + const char *zFilterUuid = 0; | |
| 885 | 897 | |
| 886 | 898 | zSep = find_option("limit","l",1); |
| 887 | 899 | rn = atoi(g.argv[3]); |
| 888 | 900 | if( g.argc>4 ){ |
| 889 | 901 | zFilterUuid = g.argv[4]; |
| 890 | 902 | } |
| 891 | 903 | |
| 892 | - rptshow( rn, zSep, zFilterUuid ); | |
| 904 | + rptshow( rn, zSep, zFilterUuid ); | |
| 905 | + | |
| 906 | + } | |
| 907 | + }else{ | |
| 908 | + enum { set,add,err } eCmd = err; | |
| 909 | + int i; | |
| 910 | + int rid; | |
| 911 | + const char *zTktUuid; | |
| 912 | + Blob tktchng, cksum; | |
| 913 | + | |
| 914 | + /* get command type (set/add) and get uuid, if needed for set */ | |
| 915 | + if( strncmp(g.argv[2],"set",n)==0 ){ | |
| 916 | + eCmd = add; | |
| 917 | + if( g.argc==3 ){ | |
| 918 | + fossil_fatal("set: missing TICKETUUID!"); | |
| 919 | + } | |
| 920 | + zTktUuid = g.argv[3]; | |
| 921 | + i=4; | |
| 922 | + }else if( strncmp(g.argv[2],"add",n)==0 ){ | |
| 923 | + eCmd = set; | |
| 924 | + zTktUuid = 0; | |
| 925 | + i = 3; | |
| 926 | + } | |
| 927 | + if( eCmd==err ){ | |
| 928 | + fossil_fatal("%s: unknown ticket command",g.argv[2]); | |
| 929 | + } | |
| 930 | + if( i==g.argc ){ | |
| 931 | + fossil_fatal("empty %s command aborted!",g.argv[2]); | |
| 932 | + } | |
| 933 | + /* read all available ticket fields */ | |
| 934 | + getAllTicketFields(); | |
| 935 | + /* read commandline and assign fields in the azValue array */ | |
| 936 | + while( i<g.argc ){ | |
| 937 | + char *zFName; | |
| 938 | + char *zFValue; | |
| 939 | + int j; | |
| 940 | + | |
| 941 | + zFName = g.argv[i++]; | |
| 942 | + if( i==g.argc ){ | |
| 943 | + fossil_fatal("missing value for '%s'!",zFName); | |
| 944 | + } | |
| 945 | + zFValue = g.argv[i++]; | |
| 946 | + j = fieldId(zFName); | |
| 947 | + if( j == -1 ){ | |
| 948 | + fossil_fatal("unknown field name '%s'!",zFName); | |
| 949 | + }else{ | |
| 950 | + azValue[j] = zFValue; | |
| 951 | + } | |
| 952 | + } | |
| 953 | + blob_zero(&tktchng); | |
| 954 | + { /* add the time to the ticket manifest */ | |
| 955 | + char *zDate; | |
| 956 | + | |
| 957 | + zDate = db_text(0, "SELECT datetime('now')"); | |
| 958 | + zDate[10] = 'T'; | |
| 959 | + blob_appendf(&tktchng, "D %s\n", zDate); | |
| 960 | + free(zDate); | |
| 961 | + } | |
| 962 | + /* append defined elements */ | |
| 963 | + for(i=0; i<nField; i++){ | |
| 964 | + char *zValue; | |
| 893 | 965 | |
| 966 | + zValue = azValue[i]; | |
| 967 | + if( azValue[i] && azValue[i][0] ){ | |
| 968 | + if( strncmp(azField[i], "private_", 8)==0 ){ | |
| 969 | + zValue = db_conceal(zValue, strlen(zValue)); | |
| 970 | + blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); | |
| 971 | + }else{ | |
| 972 | + blob_appendf(&tktchng, "J %s %#F\n", azField[i], strlen(zValue), zValue); | |
| 973 | + } | |
| 974 | + } | |
| 975 | + } | |
| 976 | + if( zTktUuid ){ | |
| 977 | + zTktUuid = db_text(0, | |
| 978 | + "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", zTktUuid | |
| 979 | + ); | |
| 980 | + }else{ | |
| 981 | + zTktUuid = db_text(0, "SELECT lower(hex(randomblob(20)))"); | |
| 982 | + } | |
| 983 | + blob_appendf(&tktchng, "K %s\n", zTktUuid); | |
| 984 | + blob_appendf(&tktchng, "U %F\n", g.zLogin); | |
| 985 | + md5sum_blob(&tktchng, &cksum); | |
| 986 | + blob_appendf(&tktchng, "Z %b\n", &cksum); | |
| 987 | + rid = content_put(&tktchng, 0, 0); | |
| 988 | + if( rid==0 ){ | |
| 989 | + fossil_panic("trouble committing ticket: %s", g.zErrMsg); | |
| 894 | 990 | } |
| 895 | - }else if( strncmp(g.argv[2],"set",n)==0 ){ | |
| 896 | - fossil_fatal("set unimplemented"); | |
| 897 | - }else if( strncmp(g.argv[2],"add",n)==0 ){ | |
| 898 | - fossil_fatal("add unimplemented"); | |
| 991 | + manifest_crosslink_begin(); | |
| 992 | + manifest_crosslink(rid, &tktchng); | |
| 993 | + manifest_crosslink_end(); | |
| 899 | 994 | } |
| 900 | 995 | } |
| 901 | 996 | } |
| 902 | 997 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -848,11 +848,11 @@ | |
| 848 | ** If TICKETFILTER is given on the commandline, the query is |
| 849 | ** limited with a new WHERE-condition. |
| 850 | ** example: Report lists a column # with the uuid |
| 851 | ** TICKETFILTER= [#]='uuuuuuuuu' |
| 852 | ** |
| 853 | ** %fossil ticket set FIELD VALUE ?FIELD VALUE ... ? TICKETUUID |
| 854 | ** |
| 855 | ** change ticket identified by TICKETUUID and set the value of |
| 856 | ** field FIELD to VALUE. Valid field descriptions are: |
| 857 | ** status, type, severity, priority, resolution, |
| 858 | ** foundin, private_contact, resolution, title or comment |
| @@ -867,35 +867,130 @@ | |
| 867 | ** |
| 868 | */ |
| 869 | void ticket_cmd(void){ |
| 870 | int n; |
| 871 | |
| 872 | db_find_and_open_repository(1); |
| 873 | |
| 874 | if( g.argc<3 ){ |
| 875 | usage("add|set|show"); |
| 876 | }else{ |
| 877 | n = strlen(g.argv[2]); |
| 878 | if( strncmp(g.argv[2],"show",n)==0 ){ |
| 879 | if( g.argc==3 ){ |
| 880 | usage("ticket show REPORTNR"); |
| 881 | }else{ |
| 882 | int rn; |
| 883 | const char *zSep = 0; |
| 884 | const char *zFilterUuid = 0; |
| 885 | |
| 886 | zSep = find_option("limit","l",1); |
| 887 | rn = atoi(g.argv[3]); |
| 888 | if( g.argc>4 ){ |
| 889 | zFilterUuid = g.argv[4]; |
| 890 | } |
| 891 | |
| 892 | rptshow( rn, zSep, zFilterUuid ); |
| 893 | |
| 894 | } |
| 895 | }else if( strncmp(g.argv[2],"set",n)==0 ){ |
| 896 | fossil_fatal("set unimplemented"); |
| 897 | }else if( strncmp(g.argv[2],"add",n)==0 ){ |
| 898 | fossil_fatal("add unimplemented"); |
| 899 | } |
| 900 | } |
| 901 | } |
| 902 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -848,11 +848,11 @@ | |
| 848 | ** If TICKETFILTER is given on the commandline, the query is |
| 849 | ** limited with a new WHERE-condition. |
| 850 | ** example: Report lists a column # with the uuid |
| 851 | ** TICKETFILTER= [#]='uuuuuuuuu' |
| 852 | ** |
| 853 | ** %fossil ticket set TICKETUUID FIELD VALUE ?FIELD VALUE ... ? |
| 854 | ** |
| 855 | ** change ticket identified by TICKETUUID and set the value of |
| 856 | ** field FIELD to VALUE. Valid field descriptions are: |
| 857 | ** status, type, severity, priority, resolution, |
| 858 | ** foundin, private_contact, resolution, title or comment |
| @@ -867,35 +867,130 @@ | |
| 867 | ** |
| 868 | */ |
| 869 | void ticket_cmd(void){ |
| 870 | int n; |
| 871 | |
| 872 | db_must_be_within_tree(); |
| 873 | db_find_and_open_repository(1); |
| 874 | |
| 875 | user_select(); |
| 876 | /* |
| 877 | ** Check that the user exists. |
| 878 | */ |
| 879 | if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){ |
| 880 | fossil_fatal("no such user: %s", g.zLogin); |
| 881 | } |
| 882 | fprintf(stdout,"%s\n",g.zLogin); |
| 883 | |
| 884 | if( g.argc<3 ){ |
| 885 | usage("add|set|show"); |
| 886 | }else{ |
| 887 | n = strlen(g.argv[2]); |
| 888 | if( n==1 && g.argv[2][0]=='s' ){ |
| 889 | usage("ticket show|set|add"); |
| 890 | }else if( strncmp(g.argv[2],"show",n)==0 ){ |
| 891 | if( g.argc==3 ){ |
| 892 | usage("ticket show REPORTNR"); |
| 893 | }else{ |
| 894 | int rn; |
| 895 | const char *zSep = 0; |
| 896 | const char *zFilterUuid = 0; |
| 897 | |
| 898 | zSep = find_option("limit","l",1); |
| 899 | rn = atoi(g.argv[3]); |
| 900 | if( g.argc>4 ){ |
| 901 | zFilterUuid = g.argv[4]; |
| 902 | } |
| 903 | |
| 904 | rptshow( rn, zSep, zFilterUuid ); |
| 905 | |
| 906 | } |
| 907 | }else{ |
| 908 | enum { set,add,err } eCmd = err; |
| 909 | int i; |
| 910 | int rid; |
| 911 | const char *zTktUuid; |
| 912 | Blob tktchng, cksum; |
| 913 | |
| 914 | /* get command type (set/add) and get uuid, if needed for set */ |
| 915 | if( strncmp(g.argv[2],"set",n)==0 ){ |
| 916 | eCmd = add; |
| 917 | if( g.argc==3 ){ |
| 918 | fossil_fatal("set: missing TICKETUUID!"); |
| 919 | } |
| 920 | zTktUuid = g.argv[3]; |
| 921 | i=4; |
| 922 | }else if( strncmp(g.argv[2],"add",n)==0 ){ |
| 923 | eCmd = set; |
| 924 | zTktUuid = 0; |
| 925 | i = 3; |
| 926 | } |
| 927 | if( eCmd==err ){ |
| 928 | fossil_fatal("%s: unknown ticket command",g.argv[2]); |
| 929 | } |
| 930 | if( i==g.argc ){ |
| 931 | fossil_fatal("empty %s command aborted!",g.argv[2]); |
| 932 | } |
| 933 | /* read all available ticket fields */ |
| 934 | getAllTicketFields(); |
| 935 | /* read commandline and assign fields in the azValue array */ |
| 936 | while( i<g.argc ){ |
| 937 | char *zFName; |
| 938 | char *zFValue; |
| 939 | int j; |
| 940 | |
| 941 | zFName = g.argv[i++]; |
| 942 | if( i==g.argc ){ |
| 943 | fossil_fatal("missing value for '%s'!",zFName); |
| 944 | } |
| 945 | zFValue = g.argv[i++]; |
| 946 | j = fieldId(zFName); |
| 947 | if( j == -1 ){ |
| 948 | fossil_fatal("unknown field name '%s'!",zFName); |
| 949 | }else{ |
| 950 | azValue[j] = zFValue; |
| 951 | } |
| 952 | } |
| 953 | blob_zero(&tktchng); |
| 954 | { /* add the time to the ticket manifest */ |
| 955 | char *zDate; |
| 956 | |
| 957 | zDate = db_text(0, "SELECT datetime('now')"); |
| 958 | zDate[10] = 'T'; |
| 959 | blob_appendf(&tktchng, "D %s\n", zDate); |
| 960 | free(zDate); |
| 961 | } |
| 962 | /* append defined elements */ |
| 963 | for(i=0; i<nField; i++){ |
| 964 | char *zValue; |
| 965 | |
| 966 | zValue = azValue[i]; |
| 967 | if( azValue[i] && azValue[i][0] ){ |
| 968 | if( strncmp(azField[i], "private_", 8)==0 ){ |
| 969 | zValue = db_conceal(zValue, strlen(zValue)); |
| 970 | blob_appendf(&tktchng, "J %s %s\n", azField[i], zValue); |
| 971 | }else{ |
| 972 | blob_appendf(&tktchng, "J %s %#F\n", azField[i], strlen(zValue), zValue); |
| 973 | } |
| 974 | } |
| 975 | } |
| 976 | if( zTktUuid ){ |
| 977 | zTktUuid = db_text(0, |
| 978 | "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", zTktUuid |
| 979 | ); |
| 980 | }else{ |
| 981 | zTktUuid = db_text(0, "SELECT lower(hex(randomblob(20)))"); |
| 982 | } |
| 983 | blob_appendf(&tktchng, "K %s\n", zTktUuid); |
| 984 | blob_appendf(&tktchng, "U %F\n", g.zLogin); |
| 985 | md5sum_blob(&tktchng, &cksum); |
| 986 | blob_appendf(&tktchng, "Z %b\n", &cksum); |
| 987 | rid = content_put(&tktchng, 0, 0); |
| 988 | if( rid==0 ){ |
| 989 | fossil_panic("trouble committing ticket: %s", g.zErrMsg); |
| 990 | } |
| 991 | manifest_crosslink_begin(); |
| 992 | manifest_crosslink(rid, &tktchng); |
| 993 | manifest_crosslink_end(); |
| 994 | } |
| 995 | } |
| 996 | } |
| 997 |