How do you specify the classpath with Leiningen? - clojure

In Clojure, I have a Leiningen project with my source in
/src/project/core.clj
I want to add a subdirectory to this. Eg.
/src/project/examples/example-one.clj
In my core.clj file I try to pull in from
project.examples.example-one
But lein compile still tells me
Could not locate project/examples/example_one__init.class or project/examples/example_one.clj on classpath:
Do you have to explicitly update project.clj file if you add a subdirectory to your main code directory? (I don't see that the main code directory itself is given there explicitly.)

if your namespace contains dashes, the corresponding file should contain underscores instead of those dashes. You can read about the reason in here:
why-does-clojure-convert-dashes-in-names-to-underscores-in-the-filesystem
Unless you add different source codes like Java, Groovy etc... by default lein will include all the namespaces in the src folder.

Ah ... seems I can't have a hyphen in file name?
Kind of weird for a Lisp dialect, now I've got used to using hyphens as the default separator in my function names.

Related

Where should the file user.clj go?

I am trying to setup proto-repl atom-editor package and apparently it needs a file user.clj to exist somewhere - which I guess is some leiningen's init file.
Where should I create this file?
Clojure will load the file user.clj from your class path if it is found. In a default leinengen project src/ will be on the class path, so if you create src/user.clj the contents of that file will be loaded in the context of the user namespace.
user is the default namespace for the clojure repl, but some leiningen projects override this. In order to access definitions in user.clj you will need to either pull user into scope (using require or use) or make sure that user is your starting namespace.
See the Proto REPL demo project https://github.com/jasongilman/proto-repl-demo/blob/master/dev/user.clj for an example of how to setup user.clj You should also add a dependency on clojure.tools.namespace in the project.clj https://github.com/jasongilman/proto-repl-demo/blob/master/project.clj
I just pushed some changes to Proto REPL last night to improve this area but you'll still benefit from having one setup.
According to the proto-repl page, it might use some functions from user namespace when reloading code in REPL (reset function) but it shouldn't be required.
You might want to take a look at the proto-repl demo project to see the more advanced setup.

Git - Ignore directories based on their contents

Using .gitignore, is there a way to ignore a directory if it contains a certain file (or directory)?
This would be something like look-ahead assertions, though my use case is a little different: I want to ignore Mercurial repos in my project, to keep from accidentally committing them as part of the project. That is, I want to ignore all directories containing .hg, not just .hg itself.
I can work around this using the answer from this question, adding each directory name to .gitignore, but I'd like to make it more general if I can.
There is no way to do it beside adding all of them to your .gitignore file.
What you can do it to write a scipt which append all the desired paths to your .gitignore.
The content of .gitignore is alist of paths so git can be configured based upon content.
Each line in a gitignore file specifies a pattern

Get leiningen project root directory

How do I get leiningen project's root directory at runtime?
My problem is that I want to place my sqlite file at the root directory, and access it via source code at different source file.
I don't like to use relative path, so how should I do?
Here are two ways to get the full path of the current working directory, which will be the project's home directory when you start Clojure using lein repl or lein run:
(System/getProperty "user.dir")
and
(.getCanonicalPath (clojure.java.io/file "."))
In the second method, you can insert any path string instead of ".", and it will be interpreted relative to Clojure's current working directory if the string doesn't contain an initial backslash. (I'm not sure whether the behavior is exactly the same on a Windows system.)
(The first method comes from this question; the answers there might be useful for your situation.)
Can you put the sqlite file in the resources folder and then you could use clojure.java.io/resource to retrieve it at run time?

Can org-mode babel tangle produce leiningen directories?

We want to automate the production of a Leiningen project tree
entirely from an org-mode babel file. We want to do this so that we
can also create beautiful, typeset documentation via
org-latex-export-to-pdf. We want no less than full literate
programming in Clojure from org-mode.
The following command:
$ lein new ex1
produces a tree that looks like this:
ex1
ex1/.gitignore
ex1/doc
ex1/doc/intro.md
ex1/project.clj
ex1/README.md
ex1/resources
ex1/src
ex1/src/ex1
ex1/src/ex1/core.clj
ex1/test
ex1/test/ex1
ex1/test/ex1/core_test.clj
We want to do the identical thing just by running
org-babel-tangle, and no more, in our org-mode buffer in
emacs.
A difficulty arises: whereas tangle is happy to produce
files in existing subdirectories like src and test, it seems reluctant to produce the subdirectories if they don't exist. That means we must
create the directory structure by some other means -- unless we can
get tangle to do it for us, and that's the subject of this
StackOverflow question.
There are six files in the directory structure created by Leiningen. I can remove them all and re-create them from my org-file with BEGIN_SRC blocks such as the following
#+BEGIN_SRC clojure :tangle ./ex1/src/ex1/core.clj
(ns ex1.core)
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
#+END_SRC
Notice particularly the name of the subdirectory path
#+BEGIN_SRC clojure :tangle ./ex1/src/ex1/core.clj
All is well if our directory structure already exists. org-mode's tangle will
create or update all six files described above and create new files in any existing directory. We don't know how to
get tangle to produce the directories; it complains that there is no such
directory.
A copy of the desired .org file can be found here if you would like more details.
It is possible use the following header in the begin_src section,
:mkdirp yes
FYI There's now a lein project template for using org based projects:
https://github.com/thi-ng/thing-babel

Clojure load files

I'm trying to set up a simple clojure project, and I'm not sure how to load files between the project. I'm sure that the answer is in the documentation, but I can't find a simple answer any where and I'm not sure where to look.
Essentially, my directory looks like this:
Clojure/
clojure/
clojure.jar
other clojure files
clojure-contrib/
clojure-contrib.jar
other contrib files
project/
main.clj
utils.clj
And I want main.clj to be something like this:
(ns project.main
(:require project.utils))
(greet)
and utils.clj to be something like this:
(ns project.utils)
(defn greet [] (println "Hello, World!"))
But that fails with:
Exception in thread "main" java.io.FileNotFoundException: Could not locate project/utils__init.class or project/utils.clj on classpath: (main.clj:1)
When I attempt to run it. My classpath includes the top Clojure/ directory and both jars. I also tried putting the project/ directory in the classpath as well, with no luck.
How do you set up a simple clojure project?
You don't mention what your environment is (i.e. Emacs/SLIME/Swank, vim/Vimclojure), so I'm going to assume you are trying to invoke it from the command line.
You need to have your Clojure/ project directory in the classpath:
java -cp path/to/clojure.jar:path/to/clojure-contrib.jar:path/to/Clojure ...
Make sure to check that paths are correct relative to current working directory. It needs to point to the root of your namespace (i.e. if running in Clojure/, the path is .).
In fact, your project layout Works On My Machine(tm), with the exception that I have use instead of require (but you should've got a different error anyway if you got to the point when Clojure could find all your files).
This answer I posted to another question should hopefully give you an idea of how your filenames should relate to namespace names for things to work. However, since your question is "how to set up a simple Clojure project", the following is a better start:
Go to GitHub and grab Leiningen.
Follow the instructions in the README. You'll end up doing something like
$ lein new my-project
$ cd my-project
# ... edit project.clj ...
$ lein deps
Hack away! You'll need to put your files in the correct places. That will mean putting your source files in the directory tree rooted at my-project/src, with your core namespace most likely residing at my-project/src/my_project/core.clj. But really, I've explained all the details in the answer linked to above, so please read it (and do leave a comment if I missed something). :-)
Leiningen will take care of the basic project layout and setting up the classpath for a REPL / swank / nailgun for you (if you haven't yet come across the latter two, you will soon -- but that's a separate topic, the swank part of which I have covered to a certain degree e.g. in this SO answer), so hopefully you'll never need to deal with the java -cp ... nonsense by hand. (The swank-related answer I linked to in the last parenthetical remark has details on how to set up swank with the correct classpath from within Emacs.)