SquareCrow
SquareCrow

Reputation: 311

Racket: How to retrieve the path of the running file?

I need a way to get the path of the running script (the directory that contains the source file), but

(current-directory) 

never points there (in this case an external drive), but rather to some predefined location.

I created a file to try all the 'find-system-path's, but none of them are the running file! The Racket docs are not helping.

#lang web-server/insta
(define (start request)
  (local [{define (build-ul items)
       `(ul ,@(map itemize items))}
      {define (itemize item)
        `(li ,(some-system-path->string (find-system-path item)))}]
(response/xexpr
`(html
  (head (title "Directories"))
  (body (h1 ,"Some Paths")
        (p ,(build-ul special-paths)))))))

(define special-paths (list 'home-dir 
                        'pref-dir 
                        'pref-file 
                        'temp-dir
                        'init-dir 
                        'init-file 
                        ;'links-file ; not available for Linux
                        'addon-dir
                        'doc-dir 
                        'desk-dir 
                        'sys-dir 
                        'exec-file 
                        'run-file
                        'collects-dir 
                        'orig-dir))

The purpose is for a local web-server application (music server) that will modify sub-directories under the directory that contains the source file. I will be carrying the app on a USB stick, so it needs to be able to locate its own directory as I carry it between machines and operating systems with Racket installed.

Upvotes: 8

Views: 2280

Answers (2)

Eli Barzilay
Eli Barzilay

Reputation: 29556

Easy way: take the running script name, make it into a complete path,then take its directory:

(path-only (path->complete-path (find-system-path 'run-file)))

But you're more likely interested not in the file that was used to execute things (the web server), but in the actual source file that you're putting your code in. Ie, you want some resources to be close to your source. An older way of doing this is:

(require mzlib/etc)
(this-expression-source-directory)

A better way of doing this is to use `runtime-path', which is a way to define such resources:

(require racket/runtime-path)
(define-runtime-path my-picture "pic.png")

This is better since it also registers the path as something that your script depends on -- so if you were to package your code as an installer, for example, Racket would know to package up that png file too.

And finally, you can use it to point at a whole directory:

(define-runtime-path HERE ".")
... (build-path HERE "pic.png") ...

Upvotes: 14

Ryan Culpepper
Ryan Culpepper

Reputation: 10653

If you want the absolute path, then I think this should do it:

(build-path (find-system-path 'orig-dir)
            (find-system-path 'run-file))

Upvotes: 0

Related Questions