1+ (module CODEPOD racket
2+
3+ (require (for-syntax syntax/parse racket rackunit)
4+ racket/enter
5+ rackunit
6+ racket/string
7+ racket/list
8+ racket/port
9+ racket/format
10+ uuid)
11+
12+ (provide
13+ my-ns-enter!
14+ CODEPOD-ADD-IMPORT
15+ CODEPOD-ADD-IMPORT-NS
16+ CODEPOD-DELETE-IMPORT
17+ CODEPOD-EVAL
18+ CODEPOD-link)
19+
20+ ;; (enter! #f)
21+
22+ (compile-enforce-module-constants #f )
23+
24+ (define (ns->submod ns)
25+ (let ([names (string-split ns "/ " )])
26+ (when (not (empty? names))
27+ (let ([one (string->symbol (first names))]
28+ [two (map string->symbol (rest names))])
29+ `(submod ',one
30+ ,@two)))))
31+
32+ (define (ns->enter ns)
33+ (let ([mod (ns->submod ns)])
34+ (if (void? mod) '(void)
35+ `(dynamic-enter! ',mod))))
36+
37+ ;; (ns->enter "hello/world/aaa")
38+ ;; => '(dynamic-enter! '(submod 'hello world aaa))
39+
40+ ;; FIXME this will declare new modules every time. Instead, I should go into the module and declare a submodule
41+ (define (ns->ensure-module ns)
42+ (let loop ([names (string-split ns "/ " )])
43+ (if (empty? names) '(void)
44+ `(module ,(string->symbol (first names)) racket/base
45+ ,(loop (rest names))))))
46+ ;; (ns->ensure-module "hello/world/aaa")
47+ ;; (ns->ensure-module "")
48+
49+ ;; FIXME not working, but the expanded code works, weird
50+ (define-syntax (reset-module stx)
51+ (syntax-parse
52+ stx
53+ [(_ ns names ... )
54+ #`(module ns racket
55+ (require rackunit 'CODEPOD )
56+ (provide names ... )
57+ (define names "PLACEHOLDER " ) ... )]))
58+
59+ (define (my-ns-enter! ns)
60+ (with-handlers
61+ ([exn:fail:contract?
62+ (lambda (exn)
63+ (eval
64+ `(module ,(string->symbol ns) racket/base
65+ ;; some basic packages
66+ (require rackunit 'CODEPOD )
67+ (void)))
68+ (eval
69+ `(enter! (submod ',(string->symbol ns))))
70+ "OK2 " )])
71+ (eval
72+ `(enter! (submod ',(string->symbol ns))))
73+ "OK1 " ))
74+
75+ (define (CODEPOD-ADD-IMPORT from to name)
76+ (let ([name (string->symbol name)])
77+ ;; this must not be in a begin form together with (define ...)s
78+ ; (eval (ns->enter to))
79+ (my-ns-enter! to)
80+ ;; FIXME I cannot require it here, otherwise this file is not loaded
81+ ;; (eval (require rackunit))
82+
83+ ;; OPTION 1: will not update if the def changes!
84+ ; (eval `(define ,name (dynamic-require/expose '',(string->symbol from) ',name)))
85+ ;; OPTION 2: will update, but not work on macros
86+ ; (eval `(require/expose ',(string->symbol from) (,name)))
87+ ;; OPTION 3: seems to work, but only for provided names
88+ ;; UDPATE seems not updating either
89+ (eval `(require ',(string->symbol from)))
90+ ;; if no return expression, iracket will not send anything back
91+ "OK " ))
92+
93+ (define (CODEPOD-ADD-IMPORT-NS to nses)
94+ (my-ns-enter! to)
95+ (for ([ns (string-split nses)])
96+ (eval `(require ',(string->symbol ns))))
97+ "OK " )
98+
99+ (define (CODEPOD-DELETE-IMPORT ns name)
100+ ; (eval (ns->enter ns))
101+ (my-ns-enter! ns)
102+ (namespace-undefine-variable! (string->symbol name))
103+ "OK " )
104+
105+ (define (string->sexp s)
106+ (call-with-input-string
107+ s
108+ (λ (in)
109+ (read in))))
110+
111+ (define (CODEPOD-EVAL code ns)
112+ ;; this is required, otherwise ns->ensure-module is not executed correctly
113+ ;;
114+ ;; I'm removing this because if the #f is not entered, CODEPOD-XXX functions
115+ ;; would be undefined. I will call (enter! #f) before CODEPOD-XXX
116+ ;;
117+ ;; (enter! #f)
118+ ; (eval (ns->ensure-module ns))
119+ ; (eval (ns->enter ns))
120+ (my-ns-enter! ns)
121+ (begin0
122+ (eval (string->sexp
123+ ;; support multiple s-exps in code
124+ (~a "(begin " code ") " )))
125+ (enter! #f )))
126+
127+
128+ (define (CODEPOD-link src)
129+ (let-values ([(_ fname __) (split-path src)])
130+ (let* ([id (uuid-string)]
131+ [dir (build-path "/mount/shared/static/ " id)]
132+ [dst (build-path dir fname)]
133+ [url (build-path
134+ ; "http://api.codepod.test:4000/static/"
135+ id fname)])
136+ (make-directory* dir)
137+ (copy-file src dst)
138+ (~a "CODEPOD-link " (path->string url)))))
139+
140+ )
0 commit comments