Hello,

Here is another version of 'psyntax.library-manager.ss':

http://proteus.freeshell.org/_psyntax.library-manager-library-repositories.ss

This one takes a different approach. It introduces a
'library-repositories' parameter.

In the previous hack, each "library location" was assumed to be a set of
paths into the local filesystem. The 'library-repositories' is a bit
more abstract than that. I.e.:

(library-repositories
 (list (standard-library-repository  "/usr/local/share/ikarus")
       (my-library-repository        "/root/scheme-libraries")
       (http-library-repository      "http://crop-circles.info/scheme";)
       (dns-library-repository       "scheme.crop-circles.info")
       (sqlite-library-repository    "/root/db/scheme-libraries")))

In particular, it's a list of procedures. Each procedure does:

    library-name => resource

The resource is something that the library-loader should know how to
handle. For example, if the resource is simply a fully qualified path,
it does the usual thing. However, the resource might be something
complex like:

    "sqlite:/var/scheme.db:a/b/c"

The 'standard-library-repository' acts like the current Ikarus default.

Let's try a real example.

Here's a library on a web server:

http://proteus.freeshell.org/test-remote/breatharian/breatharian.scm

Make sure there's nothing up my sleeve:

(import (breatharian))
Unhandled exception

Let's add a library repository for that remote location:

(library-repositories
   (cons (http-library-repository "proteus.freeshell.org/test-remote")
         (library-repositories)))

And try again:

(import (breatharian))
--21:47:02--
http://proteus.freeshell.org/test-remote/breatharian/breatharian.scm
           => `breatharian.scm'
Resolving proteus.freeshell.org... 192.94.73.7
Connecting to proteus.freeshell.org|192.94.73.7|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 95 [text/plain]

100%[====================================>] 95            --.--K/s


21:47:03 (7.91 MB/s) - `breatharian.scm' saved [95/95]



Bam!

(breatharian)
10

It works.

So what does 'http-library-repository' look like?

----------------------------------------------------------------------
(define (http-library-repository remote)

  (let ( (cache (string-append "/tmp/" remote)) )

    (if (not (file-exists? cache))

        ;; (make-directory cache)

        (system
         (string-append "mkdir -p " cache)))

    (lambda (library-name)

      (let ( (local-file
              (string-append cache
                             "/"
                             (my-library-name->string library-name)
                             ".scm"))

            (remote-file
              (string-append "http://"; remote "/"
                             (my-library-name->string library-name)
                             ".scm")) )

        (if (file-exists? local-file)

            local-file

            (begin

              (if (not (file-exists? (dirname local-file)))
                  (mkdir (dirname local-file)))

              (current-directory (dirname local-file))

              (let ((status (system
                              (string-append "wget " remote-file))))

                (if (= status 0)
                    local-file
                    #f))))))))
----------------------------------------------------------------------

It uses these other procedures:

(define (mkdir path)
  (system
   (string-append "mkdir -p " path)))

(define (dirname path)

  (let loop ( (i (- (string-length path) 1)) )

    (if (char=? (string-ref path i) #\/)
        (substring path 0 i)
        (loop (- i 1)))))

(define (my-library-name->string name)

  (let loop ((name name))

    (let ((component (symbol->string (car name))))

      (cond ((null? (cdr name))
             (string-append component "/" component))

            (else

             (string-append component "/" (loop (cdr name))))))))

In this case, the 'http-library-repository' hands the library-loader a
resource it knows how to deal with; i.e. a path into the local
filesystem. In particular, a path into the library source cache that it
builds up under "/tmp".

Ed

Reply via email to