0

I like that boot lets me put all my source files in the current directory. However, I would still like to develop code that refers to a parent namespace, to make it easier to import into other projects. For example, I'd like to make all my namespaces start with the same prefix, but still have their source files reside in the current directory, like this:

(ns polysyndeton.conjunctions ...)  ; in ./conjunctions.clj

(ns polysyndeton.disjunctions ...)  ; in ./disjunctions.clj

(ns polysyndeton.util ...)          ; in ./util.clj

How can I tell boot or Clojure that any namespace starting with polysyndeton. should be found in the current directory?

Ben Kovitz
  • 4,920
  • 1
  • 22
  • 50

2 Answers2

2

I don't think it possible (without workarounds that are not recommended). Clojure uses the directory structure corresponding to the namespace segments to find source files on the classpath. So you must adhere to this structure. Also see: What are common conventions for using namespaces in Clojure?

Community
  • 1
  • 1
Michiel Borkent
  • 34,228
  • 15
  • 86
  • 149
  • Uh oh, that sounds like there's no way to do it. I wonder, though, if Clojure provides a hook somewhere, because leiningen and boot are able to put the root of the directory structure in different places. How do they do that? – Ben Kovitz Feb 11 '17 at 21:38
  • It's done by setting the classpath. https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html – Michiel Borkent Feb 12 '17 at 08:43
  • One way to work around it (and not using a symlink) is to use `load-file` to explicitly load the files from the relative or absolute file path. – Michiel Borkent Feb 12 '17 at 08:45
  • 1
    You can change the root by modifying the classpath, but you can't subvert the means by which Clojure maps namespaces to classpath-relative paths. – Alex Miller Feb 13 '17 at 03:21
  • @MichielBorkent Thanks—`load-file` does work to load the files. It doesn't seem to work with _boot test,_ though, since _boot_ needs to search for and load the files itself. – Ben Kovitz Feb 19 '17 at 15:08
  • @AlexMiller The classpath-relative mapping does appear to be the limitation making this impossible. That appears to settle the matter. I'm giving up for now—so, thanks for saving me further wasted effort. :) – Ben Kovitz Feb 19 '17 at 15:11
1

You can achieve this easily with a symlink. Note that this will map ANY strings like polysyndeton.polysyndeton.polysyndeton.{...}.util to the file util.clj:

ln -s . polysyndeton
ClojureMostly
  • 4,652
  • 2
  • 22
  • 24
  • I like this idea, but after `ls -s . polysyndeton`, _boot_ is giving me this error: `java.nio.file.FileSystemLoopException: polysyndeton/polysyndeton`. I think this is because _boot_ and/or the JVM is searching the `polysyndeton` directory recursively. I've got `:source-paths` set to `#{"polysyndeton"}`. (Analogous error with `#{"."}`.) Is there any way to limit the search for source files to a single level of depth (search just the given directory, not its subdirectories)? – Ben Kovitz Feb 13 '17 at 00:39
  • Not that I know. But why are you setting the source paths to `polysyndeton`? Wasn't the whole point of this so that you don't have to do that? It works fine for me if I do a symlink like that and require a namespace. – ClojureMostly Feb 13 '17 at 06:45
  • Setting `:source-paths` to `#{"polysyndeton"}` was my second attempt. I get the same error when `:source-paths` is `#{"."}`. Are you able to run `boot test`? – Ben Kovitz Feb 13 '17 at 17:12