Skip to content

Issue with duct/include reader macro / config.edn #23

@rune-brinckmeyer

Description

@rune-brinckmeyer

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:

  1. 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?)
  2. 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 :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions