Megatest

Check-in [d85f01faff]
Login
Overview
Comment:Added multi-node cherrypicker
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | v1.65-real-new-runs-view
Files: files | file ages | folders
SHA1: d85f01faff903302c1492dfd75c603d4303d9685
User & Date: mrwellan on 2021-02-25 11:24:28
Other Links: branch diff | manifest | tags
Context
2021-02-25
22:36
Merged some portlogger and module refactoring changes. check-in: b7a7d741be user: matt tags: v1.65-real-new-runs-view
11:24
Added multi-node cherrypicker check-in: d85f01faff user: mrwellan tags: v1.65-real-new-runs-view
2021-02-24
21:11
Added .o to deps for fossil-hash. check-in: cd3fed23c9 user: mrwellan tags: v1.65-real-new-runs-view
Changes

Added utils/fslutil.scm version [886fe6d514].





































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
;;  Copyright 2006-2017, Matthew Welland.
;; 
;; This file is part of Megatest.
;; 
;;     Megatest is free software: you can redistribute it and/or modify
;;     it under the terms of the GNU General Public License as published by
;;     the Free Software Foundation, either version 3 of the License, or
;;     (at your option) any later version.
;; 
;;     Megatest is distributed in the hope that it will be useful,
;;     but WITHOUT ANY WARRANTY; without even the implied warranty of
;;     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;     GNU General Public License for more details.
;; 
;;     You should have received a copy of the GNU General Public License
;;     along with Megatest.  If not, see <http://www.gnu.org/licenses/>.
;;

(module fslutil
   *
	
(import
 scheme
 chicken.base
 chicken.condition
 chicken.string
 chicken.time.posix
 chicken.pretty-print
 chicken.process-context
 chicken.process-context.posix
 chicken.file
 chicken.io
 chicken.port
 chicken.process
 scheme
 ;;extras
 regex
 regex-case
 matchable
 srfi-1
 srfi-69
 json
 fmt
 )

(define (portprint p . args)
  (with-output-to-port p
    (lambda ()
      (apply print args))))

;; abstract out the alist-ref a bit and re-order the params
;;
(define-inline (aref dat key)
  (alist-ref key dat equal?))

;; convert silly vectors in json data to nice clean alist
;;
(define (to-alist inlst)
  (handle-exceptions
      exn
      (begin
	(print-call-chain)
	(print inlst))
    (cond
     ((proper-list? inlst) (map to-alist inlst))
     ((or (list? inlst) ;; it is a pair
	  (pair? inlst))   (cons (car inlst) (to-alist (cdr inlst))))
     ((vector? inlst)      (to-alist (vector->list inlst)))
     (else                 inlst))))

;; columnar line printer
;;
(define (print-rows inlist)
  (define (print-line x)
    (cat (car x)
	 (space-to 10)(pad/left 3 (cadr x))
	 (space-to 25)(pad/left 3 (caddr x))
	 ))
  (fmt #t (pad-char #\  (fmt-join/suffix print-line inlist nl))))

;; from the command line pull branch, start-tag, end-tag
;;
(define (extract-history branch start-tag end-tag)
  (let* ((data      (to-alist  ;; get all the data
		      (with-input-from-pipe
			  "fossil json timeline checkin -n 0"
			  json-read)))
	 (timeline   (map (lambda (e)
			   (map pair-car->symbol e))
			  (aref (aref data "payload") "timeline"))) ;; extract the timeline alists
	 (start-flag #f)
	 (end-flag   #f))
    ;; now we have all needed data as a list of alists in time order, extract the
    ;; messages for given branch starting at start-tag and ending at end-tag
    (reverse ;; return results oldest to newest
     (filter
      (lambda (x) x)
      (map
       (lambda (entry)
	 (let ((tags (aref entry 'tags)))
	   (if (or (not tags) ;; eh?
		   (not (list? tags)))
	       (begin
		 ;; (with-output-to-port (current-error-port)
		 ;;   (lambda ()
		 ;;     (print "ERROR: bad entry. tags: " tags)))
		 #f)
	       (let* ((btag (car tags))  ;; first tag is the primary branch
		      (tags (cdr tags))  ;; remainder are actual tags
		      (cmt  (aref entry 'comment))
		      (usr  (aref entry 'user))
		      (tms  (aref entry 'timestamp)))
		 ;; (print "btag: " btag " tags: " tags " usr: " usr)
		 (if (equal? btag branch) ;; we are on the branch
		     (begin
		       (if (member start-tag tags)(set! start-flag #t))
		       (let ((res (if (and start-flag
					   (not end-flag))
				      `(,usr
					,(time->string (seconds->local-time tms) "WW%U.%w %H:%M")
					,cmt)
				      #f)))
			 (if (member end-tag tags)(set! end-flag #t))
			 res))
		     #f)))))
       (reverse timeline))))))

(define (pair-car->symbol x)
  (cons (string->symbol (car x))(cdr x)))

;; from the command line pull branch, start-tag, end-tag
;; return the list of alists in correct time order
;;
(define (extract-branch branch start-tag end-tag)
  (let* ((data       (to-alist  ;; get all the data
		      (with-input-from-pipe
			  "fossil json timeline checkin -n 0"
			json-read)))
	 (timeline   (map (lambda (e)
			   (map pair-car->symbol e))
			  (aref (aref data "payload") "timeline"))) ;; extract the timeline alists
	 ;;(timeline   (aref (aref data "payload") "timeline")) ;; extract the timeline alists
	 (start-flag #f)
	 (end-flag   #f))
    ;; now we have all needed data as a list of alists in time order, extract the
    ;; messages for given branch starting at start-tag and ending at end-tag
    (reverse ;; return results oldest to newest
     (filter
      (lambda (x) x)
      (map
       (lambda (entry)
	 (let ((tags (aref entry 'tags)))
	   (if (or (not tags) ;; eh?
		   (not (list? tags)))
	       (begin
		 ;; (with-output-to-port (current-error-port)
		 ;;   (lambda ()
		 ;;     (print "ERROR: bad entry. tags: " tags)))
		 #f)
	       (let* ((btag (car tags))  ;; first tag is the primary branch
		      (tags (cdr tags))  ;; remainder are actual tags
		      (cmt  (aref entry 'comment))
		      (usr  (aref entry 'user))
		      (tms  (aref entry 'timestamp)))
		 ;; (print "btag: " btag " tags: " tags " usr: " usr)
		 (if (equal? btag branch) ;; we are on the branch
		     (begin
		       (if (not start-flag)
			   (if (or (equal? start-tag "-")
				   (member start-tag tags))
			       (set! start-flag #t)))
		       (let ((res (if (and start-flag
					   (not end-flag))
				      (append entry (list (cons 'action 'copy)
							  (cons 'dest   #f)
							  (cons 'mode   'auto)))
				      #f)))
			 (if (member end-tag tags)(set! end-flag #t))
			 res))
		     #f)))))
       (reverse timeline))))))

(define (run-cmd-file cmdfile new-branch-name dest-node)
  (let* ((data (with-input-from-file cmdfile read)))
    (print "fossil set autosync 0")
    (print "fossil branch new "new-branch-name" "dest-node)
    (print "fossil co "new-branch-name)
    (for-each
     (lambda (node)
       (let* ((timestamp (alist-ref 'timestamp node))
	      (comment   (alist-ref 'comment   node))
	      (user      (alist-ref 'user      node))
	      (uuid      (alist-ref 'uuid      node))
	      (action    (alist-ref 'action    node))
	      (dest      (alist-ref 'dest      node))
	      (mode      (alist-ref 'mode      node))
	      (tags      (alist-ref 'tags      node))
	      (remtags   (if (list? tags)(cdr tags)'()))
	      (comfile   (conc "/tmp/"(current-user-name)"-"uuid"-comment.txt")))
	 (print "\nfossil merge --cherrypick "uuid)
	 (with-output-to-file comfile
	   (lambda ()
	     (print comment)
	     (print "From: "uuid)
	     (print "User: "user)))
	 (print "fossil commit -M "comfile)))
     data)
    (print "## fossil set autosync 1")))

(define (process-fossil branch start-tag end-tag)
  (print-rows
   (extract-history branch start-tag end-tag)))

(define usage "Usage: fslutil cmd [...]
  tlsum branch start-tag end-tag 
             : generate a timeline summary
               use - for tags to indicate n/a
               (i.e. get all)
  run cmdfile new-branch-name dest-node
             : migrate the nodes from cmdfile to dest-node
               using branch name new-branch-name
")

(define (main)
  (match
   (command-line-arguments)
   (("help")(print usage))
   (("tlsum" branch start-tag end-tag)
    (process-fossil branch start-tag end-tag))
   (("branchdat" branch start-tag end-tag)
    (pp (extract-branch branch start-tag end-tag)))
   (("run" cmdfile new-branch-name dest-node)
    (run-cmd-file cmdfile new-branch-name dest-node))
   (else
    (print "ERROR: Arguments not recognised.")
    (print usage))))

) ;; end module

(import fslutil)
(main)