-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Just started fiddling with duct and integrant, so please bear with a beginner here. I have stumbled upon what I believe may be an issue related to the duct/include reader macro.
I created a standard duct project. It works as expected from the repl:
(dev)
=> :loaded
(prep)
=> :prepped
When I embed the same files in a docker container (clojure:openjdk-8) under
/home/runner/backend
and run the repl yields this unexpected result:
(dev)
=> :loaded
(prep)
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
/home/runner/backend/dev (Is a directory)
This error eventually leads to this line in resources/backend/config.edn:
:duct.profile/dev #duct/include "dev"
Following the implementation of the duct/include reader macro reveals that duct/include processes argument "dev" through config-resource:
(defn- config-resource [path]
(or (io/resource path)
(io/resource (str path ".edn"))
(io/resource (str path ".clj"))))
Investigating this from the repl in the working project I find that:
(io/resource "dev")
=> nil
(io/resource (str "dev" ".edn"))
=> #object[java.net.URL 0x54458573 "file:/home/runeb/backend/dev/resources/dev.edn"]
while inside the container the repl gives me:
(io/resource "dev")
=> #object[java.net.URL 0x7580ef78 "file:/home/runner/backend/dev"]
(io/resource (str "dev" ".edn"))
=> #object[java.net.URL 0x29040c80 "file:/home/runner/backend/dev/resources/dev.edn"]
clearly when in the docker container (io/resource path) maps to the dev directory in the project root which is not a slurp-able resource (slurped in duct/make-include):
(defn- make-include [readers]
(fn [path]
(let [opts {:readers (merge-default-readers readers)}]
(some->> path config-resource slurp (ig/read-string opts)))))
One must conclude that the project root is somehow added to the resource search list inside the container. I sure did not put it there, and my Java-fu is not good enough to perceive how it got there, or if it is supposed to be there in the first place.
Fixing this is easy enough by being more precise with with the include statement in config.edn like this:
:duct.profile/dev #duct/include "dev.edn" ;; dev.edn more specific than dev
The questions that arise are:
- Is this fix the rigtht way to do it? Is there a reason for duct/include to refer to "dev" instead of "dev.edn" in the config.edn? (Since this is what is resolves to anyway?)
- Any clue if there is something inherently wrong with resource path?
my project.clj mentions only
:resource-paths ["resources" "target/resources"]
:resource-paths ["dev/resources"]
so I have no clue how the project root (containing the project.clj file) got into the mix..
Any enlightenment is highly appreciated :-)