forked from racket/racket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprops
executable file
·1217 lines (1159 loc) · 72.4 KB
/
props
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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/sh
#| -*- scheme -*-
exec racket -um "$0" "$@"
|#
#lang racket/base
#|
This file contains "properties" of various files and directories in the Racket
tree. Its format is briefly described below, but it is mainly intended to be
used as a command-line script -- run it with `-h' to find out how to use it.
In addition, you can make it work as a git command -- put this in a file
called "git-prop" somewhere in your path (make sure to "chmod +x" it):
#!/bin/sh
top="$(git rev-parse --show-toplevel)" || exit 1
exec "$top/collects/meta/props" "$@"
and use it as a git command: `git prop cmd args...'. This will use the script
from the work tree that you're now in, with any racket executable that happens
to be on your $PATH. This is fine, because the script reads and writes itself,
unelated to the racket version that runs it.
As described above, the format of this file makes it easy to edit manually, but
it should be considered internal and mostly manipulated by running it as a
script. Specifically, when the script updates the contents, it will write
things in a certain way regardless of how it was when the file was read in.
The data is contained in a specially marked comment. Its format is a
sequence of path and properties for it:
<path> <prop> <val> <prop> <val> ...
where <path> is a "/"-delimited string (relative to the racket root), <prop>
is one of a few known property symbols, and <val> is the assigned value. The
value is should follow the predicate specification for the property, which is
defined as `known-props' before the properties data block; note that it is
assumed that the data in this file is all valid, so take care if you edit it
manually. Properties of a directory apply to all sub-paths in it (but this
might not be the case for future properties). A property can overwrite a
previous value that was already set, which means that if you really want to set
properties manually, you can just an appropriate line at the end but note that
the data is expected to have the correct format (it is checked when properties
are set by running this file as a script).
Requiring this file builds the data table and provides an interface for
properties, intended to be used by meta tools. In these functions, `path' is a
path argument that is given as a "/"-delimited and normalized path
string (no ".", "..", "//", or a "/" suffix) relative to the racket root, and
path/s is either such a string or a list of them.
* (get-prop path/s prop [default]
#:strict? [strict? #f] #:as-string? [as-string? #f])
Returns the property value of a given path. The `default' argument is used
similarly to `hash-ref' (can be a thunk, a value, or if not specified an
exception is raised). If `strict?' is true, then the property value of the
path itself is returned, not inheriting values from parent paths. If
`as-string?' is true, then the string form of the property is returned (but
note that if there is no property value, the default is used as is in either
case). See the known-props for how properties translate to/from strings.
* (set-prop! path/s prop value
#:warn? [warn? #t] #:as-string? [as-string? #f])
Sets the value of a (known) proprty for a given path or paths. If `warn?' is
true, an exception is raised if the property is already set to the value for
the (any) path. If `as-string?' is true, then the input `value' is expected
to be a string that will be parsed according to the property's spec (and
verified in the process) -- otherwise the value is used as is with no
verification.
Note that this function does not rewrite the file, use `write-props' for
that.
* (del-prop! path/s prop #:warn? [warn? #t])
Similar to `set-prop!', except that it removes a property from the given
path (or paths). The property is removed from the path itself, so this will
have no effect if a parent path has a value. If `warn?' is true, an
exception is raised if the property is not directly set for path.
* (write-props)
Writes all properties back into *this* file. The properties are normalized:
paths and properties are sorted, redundant entries are removed. This
minimizes the data (in case the file is edited manually), and minimizes
changes to the file when it is modified.
|#
;; ----------------------------------------------------------------------------
(provide get-prop set-prop! del-prop! write-props)
;; ----------------------------------------------------------------------------
;; This could use `meta/tree/tree' in the future, it's pretty similar.
(struct Tree (name [subs #:mutable] [props #:mutable] in-db?))
(define (Tree-subs/sorted tree)
(sort (Tree-subs tree) string<?
#:key (λ (t) (symbol->string (Tree-name t))) #:cache-keys? #t))
;; Descriptors for known properties
(struct Prop (name description parse unparse))
(define props-tree (Tree #f '() '() #f))
(define known-props #f)
;; used to throw an error message that fits uses as a program and when running
;; as a script.
(define running-as-script? #f)
(define (script-name)
((compose string->symbol path-element->string file-name-from-path)
(find-system-path 'run-file)))
(define (error* who fmt . args)
(if (or running-as-script? (not who))
(apply raise-user-error (script-name) fmt args)
(apply error who fmt args)))
(define (warn fmt . args)
;; maybe it's better to use log-warning and make it show when used as a
;; script?
(fprintf (current-error-port) "warning: ~a\n" (apply format fmt args)))
(define (find-prop who pname [error-message "unknown property: ~.s"])
(if (Prop? pname)
pname ; might happen when `set-prop!' calls `get-prop'
(or (for/or ([p (in-list known-props)])
(and (eq? pname (Prop-name p)) p))
(error* who error-message pname))))
(define (path->symbols path-string)
(if (equal? "" path-string)
'()
(map string->symbol (regexp-split #rx"/" path-string))))
(define rx:bad-path
#rx"^/|/$|\\\\|(?:^|/)(|\\.\\.?)(?:/|$)")
(define rx:bad-pathchar
;; instead of checking `path-string?', just heavily restrict the set of
;; allowed characters -- so not all paths can be used with this code, but
;; such paths are mostly ones that we won't want in the code anyway so do
;; this as a sanity check for adding such paths to the repository. It may
;; need updating if more characters are allowed in the future.
#rx"[^/.a-zA-Z0-9%_+-]")
(define (validate-path-string path-string who [only-warn? #f])
(define (bad why)
(error* who "invalid path argument, expecting a ~a, got: ~e"
why path-string))
(unless (string? path-string) (bad "a string"))
(when (and ((string-length path-string) . > . 0)
(regexp-match? rx:bad-path path-string))
(bad "relative `/'-delimited string, no `/' suffix, `//', `.', or `..'"))
(when (regexp-match? rx:bad-pathchar path-string)
(if only-warn?
(warn "~s is a bad path argument" path-string)
(error* who "invalid path argument, ~s is not allowed, got: ~e\n~a~a"
(regexp-match rx:bad-pathchar path-string) path-string
"(note: if paths with this character are needed, then this"
" script needs to be exteded to allow them)"))))
(define (parse-prop-string prop str who)
(with-handlers ([exn? (λ (e) (error* who "bad value for `~a', ~a: ~s"
(Prop-name prop) (exn-message e) str))])
((Prop-parse prop) str)))
(define (get-prop path-string prop-name [default get-prop]
#:strict? [strict? #f] #:as-string? [as-string? #f])
(validate-path-string path-string 'get-prop #t) ; no errors
(define upchain
;; take the chain going up from the most specific node, so that properties
;; of a directory apply to subpaths
(let loop ([path (path->symbols path-string)]
[upchain (list props-tree)])
(define sub
(and (pair? path)
(let ([fst (car path)])
(ormap (λ (sub) (and (eq? (Tree-name sub) fst) sub))
(Tree-subs (car upchain))))))
(cond [sub (loop (cdr path) (cons sub upchain))]
[(not strict?) upchain]
[(pair? path) '()]
[else (list (car upchain))])))
(define prop (find-prop 'get-prop prop-name))
(cond [(ormap (λ (tree) (assq prop-name (Tree-props tree))) upchain)
=> (λ (x) ((if as-string? (Prop-unparse prop) values) (cdr x)))]
[(eq? get-prop default)
(error* 'get-prop "no `~s' property for \"~a\"" prop-name path-string)]
[(procedure? default) (default)]
[else default]))
(define (single->list x) (if (list? x) x (list x)))
(define (set-prop! path-string/s prop-name val/string
#:warn [warn? #t] #:as-string? [as-string? #f])
(define prop (find-prop 'set-prop! prop-name))
(define val
(if as-string? (parse-prop-string prop val/string 'set-prop!) val))
(for ([path (in-list (single->list path-string/s))])
(validate-path-string path 'set-prop!)
(if (and warn? (equal? val (get-prop path prop (gensym))))
(warn "not setting `~s' for ~s to ~a" prop-name path
"a value it already has (possibly via a containing directory)")
;; otherwise set it blindly (will be normalized away when written)
(let ([tree (tree-find path #t)])
(set-Tree-props! tree (cons (cons prop-name val)
(Tree-props tree)))))))
(define (del-prop! path-string/s prop-name #:warn? [warn? #t])
(define prop (find-prop 'del-prop! prop-name))
(for ([path (in-list (single->list path-string/s))])
(validate-path-string path 'del-prop!)
(let* ([tree (tree-find path #f)]
[props (if tree (Tree-props tree) '())])
(cond [(assq prop-name props)
(set-Tree-props! tree (filter (λ (p) (not (eq? prop-name (car p))))
props))]
[warn? (warn "no `~s' property on ~s" prop-name path)]))))
(define (tree-find path-string create?)
(let loop ([path (path->symbols path-string)] [tree props-tree])
(if (null? path)
tree
(let* ([fst (car path)]
[rst (cdr path)]
[sub (or (ormap (λ (sub) (and (eq? (Tree-name sub) fst) sub))
(Tree-subs tree))
(and create?
;; keep track of properties that are actually in the
;; db, for verification
(let ([new (Tree fst '() '()
(and (null? rst) create?))])
(set-Tree-subs! tree (cons new (Tree-subs tree)))
new)))])
(and sub (loop (cdr path) sub))))))
(define (find-root)
(let loop ([p this-file] [n 5]) ; look only a few level up
(let-values ([(base _1 _2) (split-path p)])
(and base
(or (and (andmap (λ (d) (directory-exists? (build-path p d)))
'("racket" "pkgs"))
p)
(if (> n 0)
(loop base (sub1 n))
(error* #f "could not find the racket root from ~a"
(path-only this-file))))))))
;; ----------------------------------------------------------------------------
;; Reading and writing
(require racket/file racket/path racket/list racket/string
(for-syntax racket/base))
(define-syntax (this-file stx)
(let ([src (syntax-source stx)])
(if (path? src)
(datum->syntax stx src stx)
(raise-syntax-error 'props "must be required from a file"))))
(define rx:props-start #rx#"#\\|[ \r\n]+#:begin-props *\r?\n[ \r\n]+")
(define props-end-token '#:end-props)
(define (read-props* in)
(define (malformed why [line? #t])
(error* 'read-props "malformed props file: ~a~a" why
(if line?
(let-values ([(line col pos) (port-next-location in)])
(format "at line #~a" line))
"")))
(port-count-lines! in)
(unless (regexp-match? rx:props-start in)
(malformed "beginning markup not found" #f))
(let loop ([tree #f] [prop-name #f])
(define x (read in))
(cond [(eq? x props-end-token)
;; done, check that there's no leftovers
(when prop-name (malformed "property with no value at the end"))
(unless (regexp-match? #rx#"[ \r\n]*\\|#[ \r\n]+$" in)
(malformed "unexpected text found at the end of the file"))]
[prop-name
;; register a given property value
(set-Tree-props! tree (cons (cons prop-name x) (Tree-props tree)))
(loop tree #f)]
[(string? x)
;; new path, find the node or create if none
(loop (tree-find x #t) #f)]
[(find-prop #f x "bad datum `~.s'")
;; new prop
(loop (or tree (malformed "initial property has no path")) x)]
[else (malformed (format x))])))
(define (read-props) (call-with-input-file* this-file read-props*))
(define (*write-props old new)
(let ([m (regexp-match rx:props-start old 0 #f new)])
(unless m
(error* 'write-props
"beginning markup not found while writing new file"))
(write-bytes (car m) new)
(let loop ([tree props-tree] [path ""])
(when (pair? (Tree-props tree))
(fprintf new "~s" path)
(for ([p (in-list (Tree-props tree))])
(fprintf new " ~s ~s" (car p) (cdr p)))
(newline new))
(for ([sub (in-list (Tree-subs tree))])
(loop sub (let ([s (symbol->string (Tree-name sub))])
(if (equal? "" path) s (string-append path "/" s))))))
(fprintf new "\n~s |#\n" props-end-token)))
(define (write-props)
(define known-prop-names (map Prop-name known-props))
;; normalize the tree, to minimize changes to the file and remove redundant
;; entries that could be added manually
(let loop ([tree props-tree] [up-props '()])
(define normalized-props
(for*/list ([p (in-list known-prop-names)]
[p (in-value (let ([cur (assq p (Tree-props tree))])
(and cur (not (member cur up-props)) cur)))]
#:when p)
p))
(set-Tree-props! tree normalized-props)
(when (pair? (Tree-subs tree))
(let ([up-props (append normalized-props up-props)]
[subs (Tree-subs/sorted tree)])
(set-Tree-subs! tree (for*/list ([sub (in-list subs)]
[sub (in-value (loop sub up-props))]
#:when sub)
sub))))
(and (or (pair? (Tree-subs tree)) (pair? (Tree-props tree))) tree))
(let (;; temp file in the same directory => fail early if cannot write to it
;; and make a rename possible; copy from this file to preserve being
;; executable
[temp (make-temporary-file (format "~a~~a" this-file) this-file)])
(dynamic-wind
void
(λ () (call-with-output-file* temp #:exists 'truncate
(λ (new) (call-with-input-file* this-file
(λ (old) (*write-props old new)))))
(delete-file this-file)
(rename-file-or-directory temp this-file))
(λ () (when (file-exists? temp) (delete-file temp))))))
;; ----------------------------------------------------------------------------
;; Verify this database
(define no-props-needed
'(#rx"(?:~|[.]bak)$"
#rx"(?:^|/)(?:#|[.]git)"
#rx"/compiled$"
#rx"^(?:README|bin|lib|include|[.]mailmap|add-on|zos|house-calls)$"
#rx"^collects/info-domain$"
#rx"^doc/[^/]*$"
#rx"(?:^|/)[.]DS_Store$"
#rx"^[^/]*[.](?:app|exe)$"))
(define (verify)
(define errors 0)
(define (path-warning path fmt . more)
(when (= 0 errors) (newline))
(set! errors (add1 errors))
(printf " ~a: ~a\n" (or path "<ROOT>") (apply format fmt more)))
(define (uncovered-subs path/ subs)
(for*/list ([fn (in-list (directory-list (if (equal? path/ "") "." path/)))]
[str (in-value (path-element->string fn))]
#:unless (memq (string->symbol str) subs)
[subp (in-value (string-append path/ str))]
#:unless (for/or ([rx (in-list no-props-needed)])
(regexp-match? rx subp)))
subp))
(define prop-names (map Prop-name known-props))
(define (merge-props propss path/ others)
;; Used to detect collapsible properties, might be disabled, or
;; maybe just output them to stderr if that leads to an email only
;; when there are changes.
(filter
values
(for/list ([pname (in-list prop-names)])
(define values
(for*/list ([props (in-list propss)]
[a (in-value (assq pname props))]
#:when a)
(cdr a)))
(cond [(null? values) #f]
[(memq (void) values) (cons pname (void))]
[else
(define value (car values))
(define rest (cdr values))
(define same? (andmap (λ (v) (equal? value v)) rest))
(when (and same? (pair? rest) (null? others))
(path-warning (string-append path/ "...")
"all ~s sub-properties are ~s" pname value)
;; Printing the others is usually too verbose.
;; (define rx (regexp (string-append "^" (regexp-quote path/))))
;; (define os (map (λ (o) (regexp-replace rx o "")) others))
;; (define os*
;; (if (> (length os) 20) (append (take os 20) '("...")) os))
;; (printf " others: ~a\n" (string-join os* ", "))
)
(cons pname (if same? (car values) (void)))]))))
(define (loop tree base-path base-props)
(define name (Tree-name tree))
(define path (and name (string-append base-path (symbol->string name))))
(define props (Tree-props tree))
(define all-props (append props base-props))
(define subs (Tree-subs tree))
(when (eq? '|| name)
(path-warning base-path "empty name (trailing slash?)"))
(unless (equal? (reverse (Tree-subs tree)) (Tree-subs/sorted tree))
(path-warning path "unsorted sub-paths"))
(when (and (Tree-in-db? tree) (null? props))
(path-warning path "no properties"))
(for ([p (in-list props)] #:when (member p base-props))
(path-warning path "redundant property: ~s := ~s" (car p) (cdr p)))
(define path/ ; #f for a file, "" for the root
(cond [(not path) ""]
[(directory-exists? path) (string-append path "/")]
[(file-exists? path) #f]
[else (path-warning path "Missing file/directory")
#f]))
(define others (if path/ (uncovered-subs path/ (map Tree-name subs)) '()))
(unless (assq 'responsible all-props)
(define (bad p) (path-warning p "no responsible"))
(if path/ (for-each bad others) (bad path)))
(if path/
(let* ([rs (for/list ([sub (in-list subs)]) (loop sub path/ all-props))]
[others (append others (map (λ (x) (string-append path/ x))
(append-map car rs)))])
(cons others (merge-props (cons props (map cdr rs)) path/ others)))
(cons others props)))
(define root (find-root))
(printf "Root: ~a..." root)
(parameterize ([current-directory root]) (loop props-tree #f '()))
(if (errors . > . 0)
(error* #f "~s path errors" errors)
(printf " no errors.\n")))
;; ----------------------------------------------------------------------------
;; Main
(provide main)
(define (main . args)
(define (usage what)
(error* #f "~a, use \"help\" for more info" what))
(define (help . _)
(define (para . lines)
(newline)
(for ([line lines]) (printf " ~a\n" line)))
(printf "Usage: ~a subcommand args ...\n" (script-name))
(para
"This is a utility for manipulating properties in the PLT repository."
"Each of the following subcommands expects a property name from a set of"
"known properties. The given paths are normalized to be relative to the"
"racket root for the tree holding this script *if* it is in such a tree"
"(determined by inspecting a few known directories), otherwise an error"
"is raised."
""
"Note: this script holds the data that it changes, so you need to commit"
"it after changes are made."
""
"Note: it does not depend on the racket installation that runs it -- you"
"just need to use the script from the work directory that you want to"
"deal with; if you add a git alias like:"
" prop = \"!$(git rev-parse --show-toplevel)/collects/meta/props\""
"to your global git config file (usually ~/.gitconfig), then you'll be"
"able to run it as `git prop' (the first part of this finds the root of"
"your workdir)."
""
"Path arguments can also be given via stdin (each on a line) if the"
"command-line path argument is a single `-'. In this mode the paths are"
"not normalized, and it is intended for infrastructure scripts only.")
(printf "\nAvailable subcommands:\n")
(for ([v (in-list (verbs))]) (printf " ~a\n" (cadr v)))
(printf "\nKnown properties:\n")
(for ([p (in-list known-props)])
(printf " ~s: ~a\n" (Prop-name p) (Prop-description p)))
(para "See in-script comments for a racket interface"))
(define (verbs)
`([("help" "h" "-h" "--help") "help: show this help" ,help]
[("get") "get <prop> <path/s>" ,get]
[("set") "set <prop> <val> <path/s>" ,set]
[("del") "del <prop> <path/s>" ,del]
[("mv") "mv <path> <path>" ,mv]
[("verify") "verify: check that paths exist" ,verify]))
(define check-existing-paths? #t)
(define (paths->list path paths)
(if (and (equal? "-" path) (null? paths))
(for/list ([p (in-lines (current-input-port))]) p)
(let ([root (normalize-path (find-root))])
(define (norm p)
(unless (or (not check-existing-paths?)
(file-exists? p)
(directory-exists? p))
(error* #f "path does not exist: ~s" p))
(let ([n (find-relative-path root (normalize-path p))])
(if (equal? n root)
""
(let* ([n (path->string n)]
[n (case (system-type)
[(windows) (regexp-replace* #rx"\\\\" n "/")]
[else n])])
(if (regexp-match #rx"^\\.\\.(?:/|$)" n)
(error* #f "path is not in the racket tree: ~s" p)
n)))))
(if (null? paths) (norm path) (map norm (cons path paths))))))
(define (get prop path . paths)
(let ([prop (string->symbol prop)]
[seq (paths->list path paths)])
(if (not (list? seq))
;; single path: don't show it, and error if none
(printf "~a\n" (get-prop seq prop #:as-string? #t))
;; multiple paths: show them, ignore errors
(for ([p (in-list seq)])
(let ([v (get-prop p prop (void) #:as-string? #t)])
(unless (void? v) (printf "~a: ~s\n" p v)))))))
(define (set prop val path . paths)
(let ([prop (string->symbol prop)])
(set-prop! (paths->list path paths) prop val #:as-string? #t)
(write-props)))
(define (del prop path . paths)
(set! check-existing-paths? #f)
(del-prop! (paths->list path paths) (string->symbol prop))
(write-props))
(define (mv from to)
(set! check-existing-paths? #f)
(let ([nonesuch (gensym 'none)]
[from (paths->list from null)]
[to (paths->list to null)])
(for ([p (in-list (map Prop-name known-props))])
(let ([v (get-prop from p nonesuch #:strict? #t)])
(unless (eq? v nonesuch)
(set-prop! to p v)
(del-prop! from p)))))
(write-props))
(set! running-as-script? #t)
;; (perhaps add some `--force' flag to (set! check-existing-paths? #f))
(define verb (if (pair? args) (car args) (usage "missing subcommand")))
(define verb-args (cdr args))
(define proc
(or (for/or ([v (in-list (verbs))] #:when (member verb (car v))) (caddr v))
(usage (format "unknown subcommand ~s" verb))))
(if (procedure-arity-includes? proc (length verb-args))
(apply proc verb-args)
(usage (format "bad number of arguments for ~s" verb))))
;; ----------------------------------------------------------------------------
(set!
known-props
(list
;; --------------------
(Prop
'responsible
"responsible person/people (comma separated names)"
(λ (str)
(let* ([strs (remove* '("") (regexp-split #rx" *, *" str))]
[syms (map string->symbol strs)])
(cond [(ormap (λ (s) (and (not (regexp-match? #rx"^[a-z]+" s)) s)) strs)
=> (λ (s) (error (format "~s is an invalid name" s)))]
[(not (= (length syms) (length (remove-duplicates syms eq?))))
(error "repeated names")]
[else syms])))
(λ (syms) (string-join (map symbol->string syms) ",")))
;; --------------------
(Prop
'drdr:command-line
(string-join
'("command-line string"
"space-separated with \"~s\" for the file, empty => no execution,"
"missing => use the default (\"racket ~s\" for *.rkt etc,"
"\"racket -f ~s\" for *.rktl)")
"\n ")
(λ (str)
(define (bad) (error "expecting an empty string, or one with `~s'"))
(if (equal? str "")
#f
(let* ([str (regexp-replace #rx"^ +" str "")]
[str (regexp-replace #rx" +$" str "")]
[str (regexp-replace #rx" +" str " ")])
(if (equal? str "")
#f
(let* ([xs (regexp-split #rx" " str)]
[xs (cons (string->symbol (car xs))
(map (λ (x) (if (equal? x "~s") '* x)) (cdr xs)))]
[*-tail (memq '* xs)]
[commands '(racket gracket gracket-text raco mzc)])
(unless (memq (car xs) commands)
(error
(format "unidentified command \"~s\", expecting one of ~s"
(car xs) commands)))
(unless *-tail
(error "missing \"~s\" in the command"))
(when (memq '* (cdr *-tail))
(error "can't use more than a single `~s'"))
xs)))))
(λ (cmd)
(define (bad)
(error 'drdr:command-line "bad command-line value: ~.s" cmd))
(cond [(not cmd) ""]
[(not (list? cmd)) (bad)]
[else (string-join (for/list ([x (in-list cmd)])
(cond [(eq? x '*) "~s"]
[(symbol? x) (symbol->string x)]
[(string? x) x]
[else (bad)]))
" ")])))
;; --------------------
(Prop
'drdr:timeout
"timeout in seconds"
(λ (str) (if (regexp-match? #rx"^ *[0-9]+ *$" str)
(string->number str)
(error "expecting an integer")))
number->string)
;; --------------------
(Prop
'drdr:random
"is file output random?"
(λ (str) (cond [(equal? str "yes") #t]
[(equal? str "no") #f]
[else (error "expecting \"yes\" or \"no\"")]))
(λ (b) (if b "yes" "no")))))
;; read the arguments here, so just requiring this file verifies the data
(read-props)
;; ----------------------------------------------------------------------------
#| #:begin-props
".travis.yml" responsible (samth)
"INSTALL.txt" responsible (mflatt)
"Makefile" responsible (mflatt)
"README.txt" responsible (mflatt)
"build" responsible (mflatt)
"native-pkgs" responsible (mflatt)
"pkgs/algol60" responsible (mflatt robby)
"pkgs/base" responsible (mflatt)
"pkgs/cext-lib" responsible (mflatt)
"pkgs/compatibility-pkgs" responsible (eli mflatt robby samth)
"pkgs/compatibility-pkgs/compatibility-doc/mzlib" responsible (mflatt)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/contract.rkt" responsible (robby)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/foreign.rkt" responsible (eli)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/kw.rkt" responsible (eli)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/match.rkt" responsible (samth)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/plt-match.rkt" responsible (samth)
"pkgs/compatibility-pkgs/compatibility-lib/mzlib/shared.rkt" responsible (robby)
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/awk.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/binc.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/cmdline.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/compat.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/contract-mzlib-test.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/etc.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/kw.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/loadtest.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/macrolib.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/pconvert.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/restart.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/serialize.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/string-mzlib.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/structlib.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/testing.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/tests.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/threadlib.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/ttt/uinc4.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/uinc.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/uinc2.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/uinc3.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/unit.rktl" drdr:command-line #f
"pkgs/compatibility-pkgs/compatibility-test/tests/mzlib/unitsig.rktl" drdr:command-line #f
"pkgs/compiler-pkgs" responsible (mflatt jay)
"pkgs/compiler-pkgs/compiler-lib/compiler/commands/test.rkt" responsible (jay)
"pkgs/compiler-pkgs/compiler-lib/compiler/demodularizer" responsible (jay)
"pkgs/compiler-pkgs/compiler-test/tests/compiler" responsible (jay)
"pkgs/compiler-pkgs/compiler-test/tests/compiler/demodularizer/demod-test.rkt" drdr:timeout 600
"pkgs/compiler-pkgs/compiler-test/tests/compiler/embed" responsible (mflatt)
"pkgs/compiler-pkgs/compiler-test/tests/compiler/embed/embed-me4.rktl" drdr:command-line #f
"pkgs/compiler-pkgs/compiler-test/tests/compiler/embed/test.rkt" drdr:timeout 800
"pkgs/compiler-pkgs/compiler-test/tests/compiler/regression.rkt" responsible (mflatt)
"pkgs/contract-profile" responsible (stamourv)
"pkgs/data-pkgs" responsible (ryanc samth)
"pkgs/datalog" responsible (jay)
"pkgs/db-pkgs" responsible (ryanc)
"pkgs/deinprogramm" responsible (sperber)
"pkgs/deinprogramm/deinprogramm/convert-explicit.scm" drdr:command-line #f
"pkgs/deinprogramm/deinprogramm/define-record-procedures.scm" drdr:command-line #f
"pkgs/deinprogramm/deinprogramm/line3d.scm" drdr:command-line #f
"pkgs/deinprogramm/deinprogramm/quickcheck/quickcheck.scm" drdr:command-line #f
"pkgs/deinprogramm/deinprogramm/quickcheck/random.scm" drdr:command-line #f
"pkgs/distributed-places-pkgs" responsible (mflatt)
"pkgs/draw-pkgs" responsible (mflatt)
"pkgs/drracket-pkgs" responsible (robby)
"pkgs/drracket-pkgs/drracket/gui-debugger" responsible (gmarceau mflatt)
"pkgs/drracket-pkgs/drracket/lang" responsible (mflatt robby matthias)
"pkgs/drracket-pkgs/drracket/repo-time-stamp" responsible (eli)
"pkgs/drracket-pkgs/drracket-test/tests/drracket" drdr:random #t
"pkgs/drracket-pkgs/drracket-test/tests/drracket/easter-egg.rkt" drdr:timeout 480
"pkgs/drracket-pkgs/drracket-test/tests/drracket/example-tool.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/hangman.rkt" responsible (robby matthias) drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/io.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 500
"pkgs/drracket-pkgs/drracket-test/tests/drracket/language-test.rkt" responsible (robby matthias) drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 1500
"pkgs/drracket-pkgs/drracket-test/tests/drracket/memory-log.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/module-lang-test.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 800
"pkgs/drracket-pkgs/drracket-test/tests/drracket/no-write-and-frame-leak.rkt" drdr:timeout 500
"pkgs/drracket-pkgs/drracket-test/tests/drracket/repl-test-debug.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 300
"pkgs/drracket-pkgs/drracket-test/tests/drracket/repl-test-debugprofile.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 300
"pkgs/drracket-pkgs/drracket-test/tests/drracket/repl-test-misc.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/repl-test-raw.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 300
"pkgs/drracket-pkgs/drracket-test/tests/drracket/snip/run-all.rkt" drdr:timeout 800
"pkgs/drracket-pkgs/drracket-test/tests/drracket/snips.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/syncheck-test.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 200
"pkgs/drracket-pkgs/drracket-test/tests/drracket/teaching-lang-coverage.rkt" responsible (robby matthias) drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/teaching-lang-save-file.rkt" responsible (robby matthias) drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/drracket-pkgs/drracket-test/tests/drracket/teaching-lang-sharing-modules.rkt" drdr:timeout 800
"pkgs/drracket-pkgs/drracket-test/tests/drracket/teachpack.rkt" responsible (robby matthias) drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 150
"pkgs/drracket-pkgs/drracket-test/tests/drracket/test-engine-test.rkt" responsible (sperber) drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 480
"pkgs/drracket-pkgs/drracket-test/tests/jpr" responsible (mflatt)
"pkgs/ds-store-pkgs" responsible (mflatt)
"pkgs/eli-tester" responsible (eli)
"pkgs/errortrace-pkgs" responsible (mflatt)
"pkgs/errortrace-pkgs/errortrace-test/tests/errortrace/alert.rkt" responsible (eli)
"pkgs/future-visualizer-pkgs" responsible (jamesswaine)
"pkgs/gui-pkg-manager-pkgs" responsible (mflatt)
"pkgs/gui-pkgs" responsible (mflatt)
"pkgs/gui-pkgs/gui-doc/mrlib" responsible (robby)
"pkgs/gui-pkgs/gui-doc/scribblings/framework" responsible (robby)
"pkgs/gui-pkgs/gui-lib/framework" responsible (robby)
"pkgs/gui-pkgs/gui-lib/mrlib" responsible (mflatt robby)
"pkgs/gui-pkgs/gui-lib/mrlib/private/aligned-pasteboard/tests/actual-bigger.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/gui-pkgs/gui-lib/mrlib/private/aligned-pasteboard/tests/test-snip-lib.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/gui-pkgs/gui-lib/mrlib/private/aligned-pasteboard/tests/test.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/gui-pkgs/gui-lib/mrlib/private/aligned-pasteboard/tests/test2.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/gui-pkgs/gui-test/framework" responsible (robby)
"pkgs/gui-pkgs/gui-test/framework/tests/main.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 360
"pkgs/gui-pkgs/gui-test/tests/gracket/cache-image-snip-test.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/dc.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/draw-mem.rkt" drdr:random #t
"pkgs/gui-pkgs/gui-test/tests/gracket/editor.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/loadtest.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/paramz.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/testing.rktl" drdr:command-line #f
"pkgs/gui-pkgs/gui-test/tests/gracket/windowing.rktl" drdr:command-line #f
"pkgs/honu" responsible (mflatt rafkind)
"pkgs/htdp-pkgs" responsible (matthias mflatt robby)
"pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/image-util.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/image.scrbl" responsible (robby)
"pkgs/htdp-pkgs/htdp-lib/2htdp" responsible (matthias)
"pkgs/htdp-pkgs/htdp-lib/2htdp/image.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-lib/2htdp/private/image-core.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-lib/2htdp/private/image-more.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-lib/2htdp/private/img-err.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-lib/graphics" responsible (mflatt robby)
"pkgs/htdp-pkgs/htdp-lib/graphics/tests/sixlib.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-lib/stepper" responsible (clements)
"pkgs/htdp-pkgs/htdp-lib/teachpack" responsible (matthias)
"pkgs/htdp-pkgs/htdp-lib/teachpack/balls.ss" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-lib/test-engine" responsible (kathyg)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/full-scene-visible.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/image-equality-performance-htdp.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/image-equality-performance.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/on-tick-universe-with-limit.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/perform-record.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:timeout 300
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/perform-robby.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/random-seed-works.rkt" responsible (matthias) drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/record-stop-when.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/record.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/release.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/struct-universe.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *) drdr:random #t
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/test-image.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/ufo-rename.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/universe-restart.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/2htdp/tests/world0-stops.rkt" drdr:command-line (raco "test" "-m" "--fresh-user" *)
"pkgs/htdp-pkgs/htdp-test/htdp/tests/gui.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang" responsible (robby mflatt matthias)
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/advanced.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beg-adv.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beg-bega.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beg-intm.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beg-intml.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/bega-adv.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beginner-abbr.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/beginner.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/htdp-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/intermediate-lambda.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/intermediate.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/intm-adv.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/intm-intml.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/intmlam-adv.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/test-htdp.rkt" drdr:timeout 500
"pkgs/htdp-pkgs/htdp-test/tests/htdp-lang/test-image.rkt" responsible (robby)
"pkgs/htdp-pkgs/htdp-test/tests/stepper" responsible (clements)
"pkgs/htdp-pkgs/htdp-test/tests/stepper/already-defined.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/automatic-tests.rkt" drdr:timeout 600
"pkgs/htdp-pkgs/htdp-test/tests/stepper/bad-letrec-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/constructor-redexes.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/global-prim-reduction.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/image-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/intermediate-y.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/lambda-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/let-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/letrec-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/local-define-struct.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/local-test-2.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/local-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/long-error-message.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/multiply-defined.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/name-chaining.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/no-else-clause.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/non-procedure.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/print-convert-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/printing-reducing-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/procedure-display.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/right-redex.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/structures.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/symbol-identifier.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/symbols.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/syntax-error-ordering.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/test-or.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/two-tests.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/unannotated.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/undefined.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/world-test.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/stepper/write-display.rktl" drdr:command-line #f
"pkgs/htdp-pkgs/htdp-test/tests/test-engine" responsible (kathyg)
"pkgs/html-pkgs" responsible (jay mflatt)
"pkgs/icons" responsible (ntoronto)
"pkgs/images-pkgs" responsible (ntoronto)
"pkgs/lazy" responsible (eli stchang)
"pkgs/macro-debugger-pkgs" responsible (ryanc)
"pkgs/main-distribution" responsible (eli jay matthias mflatt robby)
"pkgs/main-distribution-test" responsible (eli jay matthias mflatt robby)
"pkgs/math-pkgs" responsible (ntoronto)
"pkgs/math-pkgs/math-test/math/tests/bigfloat-custodian.rkt" drdr:random #t
"pkgs/math-pkgs/math-test/math/tests/matrix-tests.rkt" drdr:timeout 120
"pkgs/mysterx" responsible (mflatt)
"pkgs/mzcom" responsible (mflatt)
"pkgs/mzcom/tests/test.rktl" drdr:command-line #f
"pkgs/mzscheme-pkgs" responsible (mflatt)
"pkgs/net-pkgs" responsible (eli jay mflatt robby)
"pkgs/net-pkgs/net-test/tests/net/stress" responsible (jay)
"pkgs/net-pkgs/net-test/tests/net/stress/websocket.rkt" drdr:random #t
"pkgs/net-pkgs/net-test/tests/net/url-port.rkt" responsible (jay) drdr:timeout 300
"pkgs/net-pkgs/net-test/tests/net/websocket" responsible (jay)
"pkgs/net-pkgs/net-test/tests/net/websocket.rkt" responsible (jay)
"pkgs/parser-tools-pkgs" responsible (mflatt)
"pkgs/pconvert-lib" responsible (robby)
"pkgs/pict-pkgs" responsible (mflatt robby)
"pkgs/pict-snip-pkgs" responsible (robby)
"pkgs/plai" responsible (jay)
"pkgs/plai/tests/test-random-mutator.rkt" responsible (jay robby)
"pkgs/planet-pkgs" responsible (robby mflatt)
"pkgs/planet-pkgs/planet-test/tests/planet" responsible (robby jay)
"pkgs/planet-pkgs/planet-test/tests/planet/run-all.rkt" drdr:timeout 500 drdr:random #t
"pkgs/plot-pkgs" responsible (ntoronto)
"pkgs/plot-pkgs/plot-doc/plot/scribblings/plot.scrbl" drdr:timeout 180
"pkgs/plot-pkgs/plot-test/plot/tests/extreme-bounds-tests.rkt" drdr:timeout 150
"pkgs/plt-services" responsible (eli mflatt)
"pkgs/plt-services/meta" responsible (eli)
"pkgs/plt-services/meta/images/taking-screenshots/racket-widget.scm" drdr:command-line #f
"pkgs/plt-services/meta/pkg-index" responsible (jay)
"pkgs/plt-services/meta/props" responsible (eli jay) drdr:command-line (racket "-um" * "verify")
"pkgs/profile-pkgs" responsible (eli samth stamourv)
"pkgs/r5rs-pkgs" responsible (mflatt)
"pkgs/r6rs-pkgs" responsible (mflatt)
"pkgs/racket-pkgs" responsible (eli jay matthias mflatt robby ryanc samth)
"pkgs/racket-pkgs/at-exp-lib" responsible (eli mflatt)
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/auto.rkt" drdr:random #t
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/mk-bigloo.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/mk-chicken.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/mk-gambit.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/r5rs-wrap.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed" responsible (stamourv samth)
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/collatz-q.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/collatz.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/cpstak.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/ctak.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/dderiv.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/deriv.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/div.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/fft.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/graphs.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/lattice2.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/maze2.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/mazefun.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/nestedloop.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/nfa.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/nothing.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/nqueens.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/nucleic3.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/paraffins.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/puzzle.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/ray.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/tak.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/takl.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/takr.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/takr2.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/common/typed/triangle.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/mz/ssax.rkt" drdr:timeout 900
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/rx/auto.rkt" drdr:timeout 600 drdr:random #t
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/auto.rkt" drdr:random #t
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/chameneos.rkt" drdr:random #t
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed" responsible (stamourv samth)
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/ackermann.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/ary.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/binarytrees.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/chameneos.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/cheapconcurrency.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/echo.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/except.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fannkuch-redux.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fannkuch.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fasta.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fibo.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/hash.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/hash2.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/heapsort.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/hello.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/k-nucleotide.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/lists.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/mandelbrot-generic.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/mandelbrot.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/matrix.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/meteor.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/moments.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nbody-generic.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nbody-vec-generic.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nbody-vec.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nbody.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nestedloop.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nothing.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nsieve.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/nsievebits.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/partialsums.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/pidigits.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/pidigits1.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/random.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/recursive.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/regexmatch.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/regexpdna.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/reversecomplement.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/reversefile.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/sieve.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/spectralnorm-generic.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/spectralnorm.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/spellcheck.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/strcat.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/sumcol.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/thread-ring.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/wc.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/wordfreq.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-doc/compatibility" responsible (asumu stamourv)
"pkgs/racket-pkgs/racket-doc/dynext" responsible (mflatt)
"pkgs/racket-pkgs/racket-doc/ffi/examples" responsible (eli)
"pkgs/racket-pkgs/racket-doc/ffi/examples/sndfile.rkt" responsible (clements)
"pkgs/racket-pkgs/racket-doc/file" responsible (mflatt)
"pkgs/racket-pkgs/racket-doc/help" responsible (robby)
"pkgs/racket-pkgs/racket-doc/json" responsible (eli)
"pkgs/racket-pkgs/racket-doc/openssl" responsible (mflatt)
"pkgs/racket-pkgs/racket-doc/pkg" responsible (jay)
"pkgs/racket-pkgs/racket-doc/scribblings" responsible (mflatt eli robby matthias)
"pkgs/racket-pkgs/racket-doc/scribblings/raco" responsible (jay mflatt)
"pkgs/racket-pkgs/racket-doc/scribblings/reference/generic.scrbl" responsible (asumu stamourv cce)
"pkgs/racket-pkgs/racket-doc/scribblings/style" responsible (matthias)
"pkgs/racket-pkgs/racket-doc/syntax" responsible (mflatt)
"pkgs/racket-pkgs/racket-doc/syntax/scribblings/parse" responsible (ryanc)
"pkgs/racket-pkgs/racket-doc/syntax/scribblings/parse.scrbl" responsible (ryanc)
"pkgs/racket-pkgs/racket-doc/version" responsible (eli)
"pkgs/racket-pkgs/racket-doc/xml" responsible (jay)
"pkgs/racket-pkgs/racket-test/tests/file" responsible (eli mflatt)
"pkgs/racket-pkgs/racket-test/tests/future" responsible (jamesswaine mflatt robby)
"pkgs/racket-pkgs/racket-test/tests/future/future.rkt" drdr:timeout 200 drdr:random #t
"pkgs/racket-pkgs/racket-test/tests/future/random-future.rkt" drdr:timeout 480 drdr:random #t
"pkgs/racket-pkgs/racket-test/tests/generic" responsible (asumu stamourv cce)
"pkgs/racket-pkgs/racket-test/tests/generic/benchmark.rkt" drdr:timeout 300 drdr:random #t
"pkgs/racket-pkgs/racket-test/tests/info.rkt" responsible (eli)
"pkgs/racket-pkgs/racket-test/tests/match" responsible (samth)
"pkgs/racket-pkgs/racket-test/tests/openssl" responsible (mflatt)
"pkgs/racket-pkgs/racket-test/tests/openssl/basic.rkt" drdr:random #t
"pkgs/racket-pkgs/racket-test/tests/pkg" responsible (jay)
"pkgs/racket-pkgs/racket-test/tests/pkg/test.rkt" drdr:timeout 1200
"pkgs/racket-pkgs/racket-test/tests/racket" responsible (mflatt)
"pkgs/racket-pkgs/racket-test/tests/racket/all.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/async-channel.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/basic.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/boundmap-test.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/bytes.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/censor.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/chaperone.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/char-set.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/cm.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/cmdline.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/collects.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/contmark.rktl" drdr:command-line #f
"pkgs/racket-pkgs/racket-test/tests/racket/contract" responsible (robby)
"pkgs/racket-pkgs/racket-test/tests/racket/contract-helpers.rkt" responsible (robby)
"pkgs/racket-pkgs/racket-test/tests/racket/contract-opt-tests.rkt" responsible (robby)
"pkgs/racket-pkgs/racket-test/tests/racket/contract-rand-test.rkt" responsible (robby)