From 840610facf5b6588e0a8d893eaa1c9f1d356af68 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sat, 25 May 2019 17:10:25 -0400 Subject: [PATCH] Add urlloader example. Demonstrate loading files from URL. --- CHANGELOG.md | 1 + examples/urlloader.janet | 28 ++++++++++++++++++++++++++++ src/boot/boot.janet | 26 +++++++++++++++++--------- 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 examples/urlloader.janet diff --git a/CHANGELOG.md b/CHANGELOG.md index 7564380c..595d89f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. ## 1.0.0 - ?? +- Add optional filters to `module/paths` to further refine import methods. - Add keyword arguments via `&keys` in parameter list. - Add `-k` flag for flychecking source. - Change signature to `compile` function. diff --git a/examples/urlloader.janet b/examples/urlloader.janet new file mode 100644 index 00000000..25163998 --- /dev/null +++ b/examples/urlloader.janet @@ -0,0 +1,28 @@ +# An example of using Janet's extensible module system +# to import files from URL. To try this, run `janet -l examples/urlloader.janet` +# from the repl, and then: +# +# (import https://raw.githubusercontent.com/janet-lang/janet/master/examples/colors.janet :as c) +# +# This will import a file using curl. You can then try +# +# (print (c/color :green "Hello!")) +# +# This is a bit of a toy example (it just shells out to curl), but it is very +# powerful and will work well in many cases. + +(defn- load-url + [url args] + (def f (file/popen (string "curl " url))) + (def res (dofile f :source url ;args)) + (try (file/close f) ([err] nil)) + res) + +(defn- check-http-url + [path] + (or (string/has-prefix? "http://" path) + (string/has-prefix? "https://" path))) + +# Add the module loader and path tuple to right places +(array/push module/paths ["HTTP" :janet-http check-http-url identity]) +(put module/loaders :janet-http load-url) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 5e960b88..b3886adb 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1638,7 +1638,7 @@ (defn- mod-filter [x path] (case (type x) - :nil true + :nil path :string (string/has-suffix? x path) (x path))) @@ -1651,12 +1651,17 @@ (def parts (string/split "/" path)) (def name (last parts)) (var ret nil) - (each [p mod-kind checker] module/paths + (each [p mod-kind checker resolver] module/paths (when (mod-filter checker path) - (def fullpath (expand-path-name p name path)) - (when (fexists fullpath) - (set ret [fullpath mod-kind]) - (break)))) + (if resolver + (when-let [res (resolver path)] + (set ret [res mod-kind]) + (break)) + (do + (def fullpath (expand-path-name p name path)) + (when (fexists fullpath) + (set ret [fullpath mod-kind]) + (break)))))) (if ret ret (let [expander (fn [[t _ chk]] (when (mod-filter chk path) @@ -1683,8 +1688,11 @@ "Evaluate a file in a new environment and return the new environment." [path & args] (def {:exit exit-on-error + :source source :compile-only compile-only} (table ;args)) - (def f (file/open path)) + (def f (if (= (type path) :core/file) + path + (file/open path))) (def newenv (make-env)) (defn chunks [buf _] (file/read f 2048 buf)) (defn bp [&opt x y] @@ -1704,8 +1712,8 @@ (debug/stacktrace f x) (if exit-on-error (os/exit 1)))) :compile-only compile-only - :source path}) - (file/close f) + :source (or source (if (= f path) "" path))}) + (when (not= f path) (file/close f)) (table/setproto newenv nil)) (def module/loaders