# \[racketscript\] Dynamically require all racket files in a directory

**URL:** <https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379>\
**Category:** RacketScript\
**Tags:** racketscript\
**Created:** [December 7, 2021, 11:04pm UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379 "2021-12-07T23:04:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kurinoku](https://avatars.discourse-cdn.com/v4/letter/k/aca169/32.png) [@kurinoku](https://racket.discourse.group/u/kurinoku)\
**Post date:** [December 7, 2021, 11:04pm UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/1 "2021-12-07T23:04:43Z")

</div>

I'm trying to dynamically require all rkt files in a directory without using any bindings of them, because they have conflicts.  
The tree is the following

```scheme
|- index.rkt
|--- commands
  |- echo.rkt
  |- another-cmd.rkt
  |- ...

```

so the idea is that each of this commands export three variables `name`, `description` and a function `execute`, I'm looking for a way to tell `racks` to include these files automatically, I tried to hack together a require transformer, yet it seems that I need at least one variable in the body of the module for it to work, I can't just visit the modules.

This is what I tried using  
visit-in.rkt

```scheme
#lang racket/base
(require racket/require
         (for-syntax racket/base
                     racket/path
                     racket/require-transform
                     syntax/parse))

(provide visit-in visit-all-rkt-in)

(define-syntax visit-in
  (make-require-transformer
    (lambda (stx)
      (syntax-parse stx
        [(_ path)
         (expand-import #'(only-in path))]
        [(_ subs ...+)
         (let-values ([(_ import-sources) ; only visit sources
                       (expand-import #'(multi-in subs ...))])
           (values '() import-sources))]
        ))))

(define-syntax visit-all-rkt-in
  (make-require-transformer
   (lambda (stx)
     (syntax-parse stx
       [(_ path:string)
        (define path/source (syntax-source #'path))
        (unless (and path/source (path-string? path/source) (absolute-path? path/source))
          (raise-syntax-error 'visit-all-rkt-in "expected path? source location" #'path))

        (let-values ([(base _name _dir?) (split-path path/source)])
          (let* ([is-rkt? (lambda (x) (path-has-extension? x #".rkt"))]
                 [dirlist (directory-list (build-path base (syntax-e #'path)))])
            (expand-import
             #`(visit-in
                path
                #,(map path->string (filter is-rkt? dirlist))))))]))))

```

and in "index.rkt"

```scheme
#lang racketscript/base

(require "visit-in.rkt"
         (visit-all-rkt-in "commands"))

```

---

<div class="post-metadata">

**Author:** ![kurinoku](https://avatars.discourse-cdn.com/v4/letter/k/aca169/32.png) [@kurinoku](https://racket.discourse.group/u/kurinoku)\
**Post date:** [December 8, 2021, 12:50am UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/2 "2021-12-08T00:50:23Z")

</div>

these two also do not work

```scheme
(define-syntax (require-folder stx)
  (syntax-parse stx
    [(_ path:string)
     (let ([base-src (syntax-source #'path)]
           [path/string (syntax-e #'path)])
       (let-values ([(base _name _dir?) (split-path base-src)])
         (with-syntax
             ([(mod-paths ...)
               (for/list ([p (in-list (directory-list (build-path base path/string)))]
                          #:when (path-has-extension? p #".rkt"))
                 (path->string (build-path path/string p)))])
           #'(begin
               (define x ($/require mod-paths))
               ...))))]))

(define-syntax (require-folder2 stx)
  (syntax-parse stx
    [(_ path:string)
     (let ([base-src (syntax-source #'path)]
           [path/string (syntax-e #'path)])
       (let-values ([(base _name _dir?) (split-path base-src)])
         (with-syntax
             ([(mod-paths ...)
               (for/list ([p (in-list (directory-list (build-path base path/string)))]
                          #:when (path-has-extension? p #".rkt"))
                 (path->string (build-path path/string p)))])
           #'(begin
               (require mod-paths)
               ...))))]))

(require-folder2 "commands")
(require-folder "commands")

```

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [December 8, 2021, 2:58am UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/3 "2021-12-08T02:58:07Z")

</div>

Okay, I'm virtually certain that I'm missing something obvious here, but is there a reason that you can't use e.g.

```scheme
(dynamic-require file #f)

```

?

---

<div class="post-metadata">

**Author:** ![kurinoku](https://avatars.discourse-cdn.com/v4/letter/k/aca169/32.png) [@kurinoku](https://racket.discourse.group/u/kurinoku)\
**Post date:** [December 8, 2021, 3:40am UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/4 "2021-12-08T03:40:51Z")

</div>

yes, I should have put it in the title that what I need is a solution for racketscript (although I did put it in the racketscript category, but I get that is not very visible)

Basically, racketscript compiles to javascript, and it seems that if you don't use any identifiers from a module, it doesnt register them as dependencies.

---

<div class="post-metadata">

**Author:** ![kurinoku](https://avatars.discourse-cdn.com/v4/letter/k/aca169/32.png) [@kurinoku](https://racket.discourse.group/u/kurinoku)\
**Post date:** [December 8, 2021, 4:10am UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/5 "2021-12-08T04:10:44Z")

</div>

After much testing, and trying to understand racketscript's compiler internals, it turns out it only registers a module as part of the dependency graph if one of the identifiers in the body of the module comes from another module, so the solution ends up like this.

```scheme
(define-syntax (require-folder* stx)
  (syntax-parse stx
    [(_ path:string)
     #:with name-bind (format-id this-syntax "name")
     (let ([base-src (syntax-source #'path)]
           [path/string (syntax-e #'path)])
       (let-values ([(base _name _dir?) (split-path base-src)])
         (with-syntax*
             ([(mod-paths ...)
               (for/list ([p (in-list (directory-list (build-path base path/string)))]
                          #:when (path-has-extension? p #".rkt"))
                 (path->string (build-path path/string p)))]
              [(tmp ...) (generate-temporaries #'(mod-paths ...))])
           #'(begin
               (begin (require (only-in mod-paths [name-bind tmp])) tmp)
               ...))))]))

```

You need to have one `provide`d binding in common throughout all the files you want to have compiled, and actually use it,. Inside the macro we use the `only-in` form to avoid any issues with conflicting bindings.

Not the prettiest solution, but it works.

Note: `$/require` seems to only be intended to work with external libraries.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [December 8, 2021, 4:18pm UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/6 "2021-12-08T16:18:24Z")

</div>

Glad to hear you found a workaround. Does RacketScript's design make sense here, or is this something that should change?

---

<div class="post-metadata">

**Author:** ![kurinoku](https://avatars.discourse-cdn.com/v4/letter/k/aca169/32.png) [@kurinoku](https://racket.discourse.group/u/kurinoku)\
**Post date:** [December 8, 2021, 5:46pm UTC](https://racket.discourse.group/t/racketscript-dynamically-require-all-racket-files-in-a-directory/379/7 "2021-12-08T17:46:44Z")

</div>

I opened two issues that might make this easier for newcomers (like me).

- [add support for $/require string literals of relative racketscript modules · Issue #278 · racketscript/racketscript · GitHub](https://github.com/racketscript/racketscript/issues/278)
- [add a flag to the compiler to add explicit dependencies · Issue #279 · racketscript/racketscript · GitHub](https://github.com/racketscript/racketscript/issues/279)

so hopefully an alternative to above could be made available to users.
