From 2eecdea571256037f4590cd981d4051de25f8d7c Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Sat, 21 Dec 2019 11:39:28 +0100 Subject: [PATCH] [#179] Current file path: *file* --- README.md | 13 +++++++++++++ sci | 2 +- src/babashka/impl/classpath.clj | 8 +++++--- src/babashka/main.clj | 21 ++++++++++++++------- test/babashka/file_var_test.clj | 17 +++++++++++++++++ test/babashka/scripts/file_var.bb | 6 ++++++ test/babashka/scripts/file_var_classpath.bb | 1 + test/babashka/scripts/loaded_by_file_var.bb | 3 +++ 8 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 test/babashka/file_var_test.clj create mode 100644 test/babashka/scripts/file_var.bb create mode 100644 test/babashka/scripts/file_var_classpath.bb create mode 100644 test/babashka/scripts/loaded_by_file_var.bb diff --git a/README.md b/README.md index 048a8ff5..c453b7cd 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,19 @@ $ echo '{:a 1} {:a 2}' | bb --stream '*input*' {:a 2} ``` +### Current file path + +This variable `*file*` contains the full path of the file that is currently +being executed: + +``` shellsession +$ cat example.clj +(prn *file*) + +$ bb example.clj +"/Users/borkdude/example.clj" +``` + ### Command-line arguments Command-line arguments can be retrieved using `*command-line-args*`. diff --git a/sci b/sci index 27893200..abe867b9 160000 --- a/sci +++ b/sci @@ -1 +1 @@ -Subproject commit 278932006626278a29b2ce4307d332531ff8af9d +Subproject commit abe867b9fbc01828728e2216f17f879cc2e9e2ac diff --git a/src/babashka/impl/classpath.clj b/src/babashka/impl/classpath.clj index 1b16611f..a1846656 100644 --- a/src/babashka/impl/classpath.clj +++ b/src/babashka/impl/classpath.clj @@ -14,7 +14,8 @@ (getResource [this resource-path] (let [f (io/file path resource-path)] (when (.exists f) - (slurp f))))) + {:file (.getCanonicalPath f) + :source (slurp f)})))) (defn path-from-jar [^java.io.File jar-file path] @@ -23,7 +24,8 @@ entry (some (fn [^JarFile$JarFileEntry x] (let [nm (.getName x)] (when (and (not (.isDirectory x)) (= path nm)) - (slurp (.getInputStream jar x))))) entries)] + {:file path + :source (slurp (.getInputStream jar x))}))) entries)] entry))) (deftype JarFileResolver [path] @@ -58,5 +60,5 @@ (comment (def l (loader "src:/Users/borkdude/.m2/repository/cheshire/cheshire/5.9.0/cheshire-5.9.0.jar")) (source-for-namespace l 'babashka.impl.cheshire) - (source-for-namespace l 'cheshire.core) + (:file (source-for-namespace l 'cheshire.core)) ) diff --git a/src/babashka/main.clj b/src/babashka/main.clj index 2b8e26dc..be146a88 100644 --- a/src/babashka/main.clj +++ b/src/babashka/main.clj @@ -20,7 +20,9 @@ [clojure.java.shell :as shell] [clojure.string :as str] [sci.addons :as addons] - [sci.core :as sci]) + [sci.core :as sci] + [sci.impl.vars :as vars] + [sci.impl.namespaces :as sci-namespaces]) (:gen-class)) (set! *warn-on-reflection* true) @@ -167,9 +169,11 @@ Everything after that is bound to *command-line-args*.")) (edn/read {;;:readers *data-readers* :eof ::EOF} *in*)) -(defn load-file* [ctx file] - (let [s (slurp file)] - (eval-string s ctx))) +(defn load-file* [ctx f] + (let [f (io/file f) + s (slurp f)] + (sci/with-bindings {vars/file-var (.getCanonicalPath f)} + (eval-string s ctx)))) (defn eval* [ctx form] (eval-string (pr-str form) ctx)) @@ -230,6 +234,7 @@ Everything after that is bound to *command-line-args*.")) load-fn (when classpath (fn [{:keys [:namespace]}] (cp/source-for-namespace loader namespace))) + _ (when file (vars/bindRoot vars/file-var (.getCanonicalPath (io/file file)))) ctx {:aliases '{tools.cli 'clojure.tools.cli edn clojure.edn wait babashka.wait @@ -241,7 +246,8 @@ Everything after that is bound to *command-line-args*.")) json cheshire.core} :namespaces {'clojure.core (assoc core-extras '*command-line-args* - (sci/new-dynamic-var '*command-line-args* command-line-args)) + (sci/new-dynamic-var '*command-line-args* command-line-args) + '*file* vars/file-var) 'clojure.tools.cli tools-cli-namespace 'clojure.edn {'read edn/read 'read-string edn/read-string} @@ -272,8 +278,9 @@ Everything after that is bound to *command-line-args*.")) System java.lang.System Thread java.lang.Thread} :load-fn load-fn} - ctx (update ctx :bindings assoc 'eval #(eval* ctx %) - 'load-file #(load-file* ctx %)) + ctx (update-in ctx [:namespaces 'clojure.core] assoc + 'eval #(eval* ctx %) + 'load-file #(load-file* ctx %)) ctx (addons/future ctx) _preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim) (eval-string ctx)) expression (if main diff --git a/test/babashka/file_var_test.clj b/test/babashka/file_var_test.clj new file mode 100644 index 00000000..909373bb --- /dev/null +++ b/test/babashka/file_var_test.clj @@ -0,0 +1,17 @@ +(ns babashka.file-var-test + (:require + [babashka.test-utils :as tu] + [clojure.test :as t :refer [deftest is]] + [clojure.string :as str])) + +(defn bb [input & args] + (apply tu/bb (when (some? input) (str input)) (map str args))) + +(deftest file-var-test + (let [[f1 f2 f3] + (str/split (bb nil "--classpath" "test/babashka/scripts" + "test/babashka/scripts/file_var.bb") + #"\n")] + (is (str/ends-with? f1 "file_var_classpath.bb")) + (is (str/ends-with? f2 "loaded_by_file_var.bb")) + (is (str/ends-with? f3 "file_var.bb")))) diff --git a/test/babashka/scripts/file_var.bb b/test/babashka/scripts/file_var.bb new file mode 100644 index 00000000..a35bf126 --- /dev/null +++ b/test/babashka/scripts/file_var.bb @@ -0,0 +1,6 @@ +(ns file-var + (:require [clojure.java.io :as io])) + +(require '[file-var-classpath]) +(load-file (io/file "test" "babashka" "scripts" "loaded_by_file_var.bb")) +(println *file*) diff --git a/test/babashka/scripts/file_var_classpath.bb b/test/babashka/scripts/file_var_classpath.bb new file mode 100644 index 00000000..9c67bd2f --- /dev/null +++ b/test/babashka/scripts/file_var_classpath.bb @@ -0,0 +1 @@ +(println *file*) diff --git a/test/babashka/scripts/loaded_by_file_var.bb b/test/babashka/scripts/loaded_by_file_var.bb new file mode 100644 index 00000000..c34fdfa2 --- /dev/null +++ b/test/babashka/scripts/loaded_by_file_var.bb @@ -0,0 +1,3 @@ +(ns loaded-by-file-var) + +(println *file*)