Hacker News new | past | comments | ask | show | jobs | submit login
Leiningen version 2.0.0 released (github.com/technomancy)
242 points by llambda on Jan 20, 2013 | hide | past | favorite | 44 comments



For those not familiar with Leiningen: it is a command-line tool that handles management of project settings, build settings, dependencies, deployments, debug console, packaging...and a whole bunch more. It is trivially extendable, and a large number of plugins already exist. If you're familiar with Ruby, it's the equivalent of the "rake", "gem", "rails", and "cap" commands all rolled into one. In short, in this programmer's opinion, Leiningen is reason enough on its own to go and learn Clojure!


I mostly hack in Python, but jballanc is not exaggerating when he says Leiningen is reason enough to learn Clojure.

It makes cabal and sbt look really bad. I would slaughter a goat for a Leiningen equivalent in Scala or Haskell.

Go has a solid enough ecosystem already that it isn't really needed.


I wonder just how hard it would be to take it and extend it for Scala. Just my musing 'cause I'm learning Ruby atm and plan on learning one of Prolog, Haskell, or Clojure next.


If you go with Clojure, you could cover learning logic programming using the core.logic (https://github.com/clojure/core.logic) library instead of Prolog.


>I wonder just how hard it would be to take it and extend it for Scala.

That would be insanely compelling.



The main problem here is that scalac is pretty slow, so you want to leave up the compiler process and just trigger an incremental compile. Last I heard this functionality was tightly coupled to SBT and not available independently. But for simpler projects it might be OK.


In recent months, they've made this available as "zinc" or something and it has been integrated with Maven.


Is there are a more extensive article around somewhere, which describes the advantages of Leiningen? Looking at the documentation it does not look that great.


In a nutshell:

All you have to do is download a little script called lein. You run it to get a skeleton project set up. Add whatever libraries/dependencies you need for the project, including the Clojure version, in the project.clj script. Then start the repl using lein ($ lein repl), and Bob's your Uncle - leiningen manages everything after that. No complicated tool chain set up, not even any need to rely on the package installers on your OS (and the usually outdated versions they provide).

I couldn't help you with an article that tells all, but that was a really compelling story for me.


I never used Scala but I'd be surprised if Maven support for Scala is at minimum.


> If you're familiar with Ruby, it's the equivalent of the "rake", "gem", "rails", and "cap" commands all rolled into one.

You can add "rvm"/"rbenv" to that list, as it manages Clojure versions, too.


Heh, I was going to add that, but that's actually a feature of Clojure itself, and not just Leiningen. What version of Clojure you're using just depends on which Clojure jar you've loaded into the JVM, so managing Clojure versions is not different than managing versions of any other library. (Another thing that Clojure has gotten really, really right.)


You should also add "bundler" along those Ruby tools (as if I'm not mistaken, bundler deals with fetching the dependencies).

Leiningen is like Maven :D


I am still pretty new to clojure, but I really wish adding jars that are not located in clojars or maven was a little easier (and more straightforward).

Yes, I could always take the Java project, rebuild and upload it myself. It would be nice to just drop the jar in the libs dir and go from there.

Maybe this is already possible (but undocumented), but with all questions out there from a simple search there is no clear way to do this that is not some sort of a hack.


Leiningen's package management is built upon Maven's package management. This means that you can add artifacts directly to your local maven repo (typically located at ~/.m2) to have them used instead. I do this frequently by checking out a project and running `mvn install` or (if it's already a Leiningen-based project) `lein install`.


Here you go: http://blog.markwatson.com/2012/07/my-simple-hack-for-using-...

From what I know, lein's policy is to make adding .jars as hard as possible.

Update: just found this other method http://www.pgrs.net/2011/10/30/using-local-jars-with-leining... which looks cleaner - just a bit harder (see the last comment).


Finding information on lein2 vs lein1 is a bit difficult. For example, one of the sibling comments points to a way to add them that worked in lein1 but not lein2. Too bad there is not a way to tell google some pages are outdated.

There is a general policy of trying to encourage repeatability with lein. Use of non-mavenized jars makes it much harder to have repeatability. I'd have to go track down the jar by hand to fork, or possibly even use the project.

However, for lein2 you can add the jar to your ```:resource-paths```. This will abuse the way resources are added to the classpath and also include the extra jar. Good for exploring, but try not to publish any projects with that.


This page discusses the issue in question: http://j.mp/repeatability

Jump to section 'Free-Floating Jars' if you're feeling impatient. :)


More features than you could possibly want: https://github.com/technomancy/leiningen/blob/master/sample....

But you'd be better off creating your own private repository than messing with free-floating jars.


This is a problem I have wrestled with on several occasions and the solution I choose is the lein-localrepo plugin.


Congrats to technomancy and all the contributors. Leiningen is a pleasure to work with.


Agreed, leinengen is a major part of what makes working with Clojure so awesome. And if you haven't tried out technomancy's work with Heroku, try spinning up an instance. It's incredibly well done.


> And if you haven't tried out technomancy's work with Heroku, try spinning up an instance. It's incredibly well done.

Could you please elaborate on that? I'm not familiar with the work he's done with Heroku.


From their website: "Heroku (pronounced her-OH-koo) is a cloud application platform – a new way of building and deploying web apps. Our service lets app developers spend 100% of their time on their application code, not managing servers, deployment, ongoing operations, or scaling." [1]

With the arrival of technomancy at heroku, they also provide a full-stack Clojure platform for your Clojure web applications, with a free version for those interested in experimenting.

[1] http://www.heroku.com/


I remember that cake and lein were merging about a year ago, and cake's major feature was fast startup time by reusing JVMs. Does anyone know if this was incorporated into lein2 - I can't see it in the release notes.


Fast startup time can be achieved through Drip[1], which is rather easy to setup for Leiningen use.

[1]: https://github.com/flatland/drip/wiki/Clojure


Shameless plug: Just because I wanted to learn how to create Leiningen plugins, I wrote a plugin to download and bootstrap drip and install it as the default Leiningen JVM.

Might want to give that a try too: https://github.com/josteink/lein-drip


Thanks! However, I'm not seeing any speedup. On lein 2.0.0, there doesn't seem to be any difference between using and not using drip. (Everything I tried got me startup times around the 28s-31s).



Was the fix just to the leinrc command, or should I update drip too (I'm using 0.1.8, installed via homebrew).

I tried it with the new leinrc command, and got the same result (in both cases I verified that drip servers were being started using `ps aux | gerp drip`, and they were).


I had this problem as well. Turns out that drip fails silently if you have Java 6. If you get drip from the checkout (very easy and instructions are at https://github.com/flatland/drip), it will work fine. Alternatively you can upgrade to Java 7.

I've filed an issue here: https://github.com/flatland/drip/issues/50


There is giter8[1] for Scala. I wish they would join forces to make an universal JVM project templating tool.

[1]: https://github.com/n8han/giter8


I'm surprised that people have not appreciated Maven more seeing how there are many praises for Leiningen.

While using Maven is like a love and hate relationship in my case, the best tool by the next door neighbour (Clojure) is apparently a Maven like tool :) (perhaps Leiningen is heavily inspired by Maven?).

People may dislike Maven but I found that nothing out there beats its features and it really takes a lot of pain away in setting up (or even maintaining/upgrading) Java projects.

I'm super glad Clojure has Leiningen. NodeJS also has a promising tool in NPM (haven't had the chance to search around for the other related build/deployment tools though).


    <project xmlns="http://maven.apache.org/POM/4.0.0
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                          http://maven.apache.org/xsd/maven-4.0.0.xsd>
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
     <name>Maven Quick Start Archetype</name>
      <url>http://maven.apache.org</url>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    </project>
vs

   (defproject leiningen.org "1.0.0"
      :description "Generate static HTML for http://leiningen.org
      :dependencies [[enlive "1.0.1"]]
      :main leiningen.web)


Granted many many many people use Eclipse/NetBeans/IntelliJ to come up with the XML.

If this is a concern, you can always use the mvn command-line passing arguments and archetype to generate the first skeleton XML.

I'm not nitpicking when it comes to XML vs LISP for configuration syntax.

Features is what I'm looking for so I would have to pass arguing minor things like this.

Thanks for the example though.


Leiningen, AFAIK, uses Maven under the hood. And I don't really think that people don't appreciate Maven enough, most people consider it to be a great tool. That being said, I've used both Maven (at my job) and Leiningen (for my personal projects) and working with Leiningen is so much easier than working with Maven! One could almost say that the build tools reflect the characteristics of the languages for which they are used. Maven is used to build Java projects so there's a lot of ceremony involved. Leiningen, on the other hand is quite simple and easy to understand from the start.


That wasn't my experience with Maven (tons of ceremony? never... :)).


I always hated Maven and... Leiningen sadly uses Maven under the hood. So I've been kinda forced to use Leiningen, at least for now (because I still don't know Clojure well enough to do without it).

Wanna quickly add a private .jar file / private repo? Good luck. Oh, it's doable, sure (I did it). But it's a major pain in the arse.

People will say: "But you shouldn't use free-floating .jars". Well, guess what... I like 100% reproducible builds that do not need to connect to Internet to be build. So now to have reproducible builds we need to have not only our DVCS but also our local Maven repository. Major major pain. I much prefer to have my jars managed by myself and commit them directly in the DVCS.

People will complain that it's not the correct to do it: but meanwhile I've got an easier time reproducing builds than they do...

During all my Java years (more than ten) I always managed to dodge Maven and the rare projects I inherited that were using Maven were utter mess. People will argue that it's because of people, like me, who don't know Maven well enough, that the entire projects (and builds) became utter junk. Whatever.

Another area where Leiningen/Maven really do not shine is when you don't have Internet access (like, you know, in companies which have separate networks, including ones non-connected to the big bag Internet).

Major major pain.

And what happens if you have an Internet connection but some high-target repo gets rooted and a major Java .jar gets replaced with a version containing an exploit?

Millions of devs account instantly owned by automagic Maven updates to your project.

It hasn't happened... Yet!

But lately we've seen enough Java exploits that one can reasonably think it's not "far fetched" to imagine that such a thing could happen.

Also I hate working in an environment which can change automagically, against my will. So I'm "staging" my development by using a dev account which has no Internet access and another one which does (it's easy to do on Linux, where you can trivially use per-user firewalling rules).

I've always been amazed at how many devs cannot correctly configure a Java classpath themselves and need to be babby-sitted by a tool like Maven.

As soon as I'll understand better how Clojure and how Clojure builds do work, I'll do just like I've always done with Java projects: custom scripts building from known good .jar files.

Not some magical tool constantly "phoning home" and being a security disaster waiting to happen...


> Leiningen sadly uses Maven under the hood.

It imports some classes from Maven in order to integrate with Maven repositories, but the vast majority of Leiningen has nothing to do with Maven.

> Wanna quickly add a private .jar file / private repo? Good luck.

It's currently a bit of a pain setting up an encrypted credentials file, but once that's set up it's very straightforward to use the s3-wagon-private repository to use an S3 bucket as a repository. It's just two extra lines to your project file.

edit: Apparently Lein 2 supports unencrypted credential files now, which makes things even easier if you have full-disk encryption (or aren't worried about your credentials being read).

> And what happens if you have an Internet connection but some high-target repo gets rooted and a major Java .jar gets replaced with a version containing an exploit?

This is an issue, but I believe there's an effort to solve this in Clojars by being stricter about verifying package signatures. Already all jars uploaded to Clojars with Leiningen 2 are signed by default AFAIK.

You can also easily change the default repositories Leiningen uses when searching for packages.

> I've always been amazed at how many devs cannot correctly configure a Java classpath themselves and need to be babby-sitted by a tool like Maven.

I suspect a sizeable majority of Clojure developers can configure a classpath, but why bother if a tool can do it for you? The prospect of manually managing a dependency tree of 20, 30 or even 100 packages is just insane when Lein can do it for you.


> It imports some classes from Maven in order to integrate with Maven repositories, but the vast majority of Leiningen has nothing to do with Maven.

To be more precise, Leiningen 2 uses Sonatype Aether for dependency resolution, unlike Leiningen 1 which actually used to include Maven.

Sonatype Aether is, I believe, also the dependency resolution library used in Maven 3 (but not Maven 2) -- but it's debatable whether it is actually a part of Maven.


I was actually thinking about the Maven indexer library that Leiningen uses for searching Maven repositories, but you raise a good point about dependency resolution no longer using Maven.


> Wanna quickly add a private .jar file / private repo?

I quickly add .jar files by creating the required structure under ~/.m2/repository (and potentially create a matching .pom file) and then update the project's POM to reference it and work from there. mvn will complain about a missing pom file.

It's also pretty easy to deploy a private .jar file to a Nexus repository (should you be running one). I've even seen people running httpd and copying the appropriate .jars and .poms in (for those who wanted to share with others).

> I much prefer to have my jars managed by myself and commit them directly in the DVCS.

I personally consider that to be an anti-pattern, especially if you can't discover what versions of JARs have been committed to version control by some form of metadata.

> Another area where Leiningen/Maven really do not shine is when you don't have Internet access (like, you know, in companies which have separate networks, including ones non-connected to the big bag Internet).

You can run both mvn and lein builds offline. However, you may have fun downloading/placing the appropriate project dependencies.


At one time, my 3rd-party repo almost hit 1GB (committed to SVN).

ANT script becoming more and more complicated. Running unit-test? running integration-test? SVN hooks? extra work, lots of...

Extra JARs (e.g.: Log4J 1.1 and Log4J 1.4) sometimes got included to the WAR or the deliverable output package because multiple projects refer to the same 3rd-party repo but individual project decided to use different versions of the library.

To his of its own, we decided not to move to Maven but instead opted for Ant+Ivy.

Thing is, Maven or Ivy is becoming a norm because _many_ people like me decided that it's the better way to go and we are ready to give up some of the things we had before.

Our build is 100% reproducible _and_ correct vs 100% reproducible _but_ maybe 90% correct.

One of the advantage of Maven (in Eclipse via m2clipse) is the less time it requires to setup 3rd-party JavaDoc _and_ the actual Java source code (assuming the author upload the Java source code to the M2 Repo). I can easily navigate to the source code because m2clipse will download it for me for free. Do that with ANT + Eclipse and I guarantee you that you will burn some time to set things up _AND_ it won't necessarily be cross-platform (often it won't work well across 2 different machines with the same OS anyway if someone decided to mess up with the actual .classpath).

>And what happens if you have an Internet connection but some high-target repo gets rooted and a major Java .jar gets replaced with a version containing an exploit?

Examples? Frequency? You can say the same with FreeBSD packaging, Debian and Ubuntu apt-get repo, or any similar systems.

Again, most of us are thankful that Maven (and IDE integration) exist. To bad you're not.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: