librelist archives

« back to archive

Proposal: Add Lein-Exec To Lein

Proposal: Add Lein-Exec To Lein

From:
Asim Jalis
Date:
2014-10-09 @ 16:25
I would like to propose incorporating lein-exec into lein.

Lein-exec allows you to write scripts in Clojure and run them with a
shebang line.

So you can write something like this:

#!/usr/bin/env lein-exec
(println "hello world")

Sharing Clojure programs as scripts makes it easier for users to modify
them. They don’t need to set up a Clojure environment or create a
toolchain. They can start tweaking the script to fit their needs.

This will help Clojure get mindshare because it will lower the barrier to
entry for Clojure hacking.

This is the main mechanism by which languages like Perl, Python, and
JavaScript have become popular. Lein-exec makes it possible for Clojure to
acquire the same viral nature.

Why not ship scripts as jar files you might ask. Well, a lot of times
people don’t want to run scripts if they don’t have access to the code.
Also if the code is right there it is easier to customize the script.

I write tools that I share with my coworkers, most of whom don’t have
Clojure installed on their machines. The particular use case I am trying to
build is to create a self-installing Clojure script.

If lein-exec was a part of lein and did not require a separate install this
would make it a lot easier to create a self-installing script.

Here is an example self-installing script for hello world in Clojure.

This could be a lot simpler and more robust if lein-exec was a part of
line. In this script I have no easy way of adding lein-exec as a plugin. I
could write a regex in Perl to do it. But all these solution seem like
hacks. The right solution feels like having lein-exec functionality in lein.

#!/bin/bash
LEIN=https://raw.github.com/technomancy/leiningen/stable/bin/lein
LEIN_EXEC=https://raw.github.com/kumarshantanu/lein-exec/master/lein-exec
LEIN_PLUGIN='{:user {:plugins [[lein-exec "0.3.4"]]}}'
if test ! -d ~/bin ; then mkdir -p ~/bin ; fi
if test ! -e ~/bin/lein      ; then curl -L $LEIN      > ~/bin/lein      ;
chmod a+x ~/bin/lein ; lein self-install ; fi
if test ! -e ~/bin/lein-exec ; then curl -L $LEIN_EXEC > ~/bin/lein-exec ;
chmod a+x ~/bin/lein-exec ; fi
if test ! -e ~/.lein/profiles.clj                  ; then echo
"$LEIN_PLUGIN" >  ~/.lein/profiles.clj ; fi
if grep lein-exec ~/.lein/profiles.clj > /dev/null ; then echo
"$LEIN_PLUGIN" >> ~/.lein/profiles.clj ; fi
lein-exec << '__CLJ_END__';
(println "hello world")
__CLJ_END__


I feel that if lein-exec was part of lein Clojure would be able to get into
the niche currently occupied by Perl/Python.

Thoughts?

Asim

Re: [leiningen] Proposal: Add Lein-Exec To Lein

From:
Phil Hagelberg
Date:
2014-10-09 @ 18:38
Asim Jalis <asimjalis@gmail.com> writes:

> I would like to propose incorporating lein-exec into lein.
>
> Lein-exec allows you to write scripts in Clojure and run them with a
> shebang line.
>
> So you can write something like this:
>
> #!/usr/bin/env lein-exec
> (println "hello world")

It's my understanding that shebang lines don't work portably with
arguments. That means that bringing the lein-exec plugin into Leiningen
wouldn't actually help with this, unless we changed the behaviour of
`lein` with no arguments to run code instead of displaying help.

It sounds like you're proposing adding a new shell script to Leiningen
instead? I consider the simplicity of the current install process to be
a pretty important part of its appeal, and I'd imagine if we added
another script, most people just wouldn't bother installing it because
it's another manual step, so you couldn't really rely on the second
script being present anyway. Right now it's very convenient that
"leiningen" refers to a specific command you can run; if that name comes
to refer to a group of related commands it muddies the waters and
introduces confusion, especially since it has had one meaning for so long.

> Sharing Clojure programs as scripts makes it easier for users to modify
> them. They don’t need to set up a Clojure environment or create a
> toolchain. They can start tweaking the script to fit their needs.
>
> This will help Clojure get mindshare because it will lower the barrier to
> entry for Clojure hacking.

It seems to me like this is something that should be provided by
Clojure, not Leiningen. Leiningen is a project automation tool, and the
functionality you're describing doesn't really have anything to do with
projects. I understand trying to convince core team to add new features
is extremely difficult, but I don't think that's a good reason to
shoehorn this into somewhere it doesn't belong.

-Phil