views:

88

answers:

3

I've been focusing on Clojure recently as a possible functional language to do systems scripting. Until, it dawned on me that having the JVM underneath means I'm limited to Java's capability.

So, how do I create a symlink? Or a hard link? I mean without (sh "ln" ...).

+2  A: 

Ah, this is indeed a pain. I'm not sure the sh option is all that bad, actually... Having said that, Ant provides a symlink task which you could use in a reasonably Clojure-friendly way through Lancet, the Ant wrapper originally introduced by Stuart Halloway in his "Programming Clojure" book and currently used internally by Leiningen. If you want to see the symlink task in action in Leiningen, have a look at this line in the 1.3.0 release.

Michał Marczyk
Also see how [the future might be better](http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html).
Michał Marczyk
I suppose every language has its warts.
qrest
Oh bother, now I'm not sure if the symlinking in lein even *works*... I suppose one ought to view this as an opportunity to test one's inner calm.
Michał Marczyk
Oh my! I see that, in the Path class, we might get an `isHidden` method. Does this imply the ability to create hidden files…? At last? The future is bright. (sorry to stray off topic…) I think the `sh` option might be your best bet; symlinks aren't really x-platform, thus the lack of support in Java.
Isaac Hodes
[Here](http://www.onyxbits.de/content/blog/patrick/how-deal-filesystem-softlinkssymbolic-links-java) is a nice write-up on how to distinguish symlinks from regular files in Java through JNI. By the way, I never got the "symlinks aren't portable" idea. At least an `.isSymbolicLink` method would be entirely cross-platform (returning `false` if the platform hosting the file does not support symlinks in the first place and maybe throwing an exception if for some reason it cannot discover the right answer), right? (Java can be exasperating.)
Michał Marczyk
Totally agree. It is aggravating, and it's the same rationale behind not supporting creating hidden files. Silly.
Isaac Hodes
+1  A: 

You could use Java Native Access to access native libs on the target host.

Simple example:

(ns jna-test
    (:import 
     (com.sun.jna Native Function)))

 (defn symlink [oldpath newpath]
    (-> (Function/getFunction "c" "symlink")
    (.invoke Integer (to-array [oldpath newpath]))))

There are also Clojure wrappers awailable: clj-native and clojure-jna

Jürgen Hötzel
A: 

It's something of a side note:

when using Clojure for system commands, if you use cake instead of leiningen it can use a persistent JVM so you dont have to wait three seconds for the JVM to start every time you run a command.

*cake is not very stable so some days it works much better than others. (as of Sep. 2010)

Arthur Ulfeldt