Zarządzanie projektami Clojure z leiningen
Z Jacek Laskowski - Wiki Projektanta Java EE
Czara goryczy z ciągłym uaktualnianiem wersji Clojure i biblioteki rozszerzającej Clojure Contrib przelała się i w końcu zebrałem się w sobie (zmusiło mnie), aby poświęcić chwilę na spróbowanie się z leiningen (w skrócie lein od nazwy skryptu uruchomieniowego). Jest to narzędzie do zarządzania projektami, którego konfiguracja jest programem w Clojure. Jest to doskonały sposób, aby w projekcie nie wyjść poza ramy Clojure, jeśli jest on językiem podstawowym (jak często i sama jego znajomość). Innymi słowy jest to odpowiednik Gradle (dla języka Groovy), Apache Maven (tu niestety "walczymy" z XML) czy Apache Ant, Apache Buildr (JRuby) i temu podobne.
Już miałem z nim spotkanie przy tworzeniu aplikacji webowej z Compojure, Ring i Hiccup, ale nie stał się moim podstawowym narzędziem. Jak to bywa, znałem, ale nieużywałem (nie pytaj mnie dlaczego, bo padnie magiczne "Nie wiem". Zdziwiony?).
Jako pracujący na codzień z Javą, gdzie prym wiodą IDE, które wspierają zarządzanie projektami i rozwojem aplikacji, mam nieodparte wrażenie, że dopóty nie będzie wsparcia dla lein w popularnych IDE dla Javy, dopóty nie będzie większego zainteresowania nim. Mam również wrażenie, że jest to jedynie problem osób migrujących z języka Java i głównym powodem tego stanu rzeczy jest...przyzwyczajenie oraz brak chęci poświęcenia większego wysiłku na rzecz bardziej dopasowanego lub bogatszego funkcjonalnie narzędzia (co w przypadku lein nie jest dla mnie takie oczywiste). Obserwuję, że osoby ze świata języków spoza JVM mają ten problem poza nimi i IDE raczej odstraszają swoją ogromnością funkcji niż przyciągają nimi do siebie.
Instalacja Leiningen
Instalacja lein opisana jest na jego stronie domowej, (która jest równocześnie jego repozytorium!) i sprowadza się do wykonania kilku poleceń:
$ wget --no-check-certificate https://github.com/technomancy/leiningen/raw/master/bin/lein $ chmod +x lein $ lein self-install $ lein version Leiningen 1.6.0-SNAPSHOT on Java 1.6.0_24 Java HotSpot(TM) 64-Bit Server VM
Można również zainstalować wersję stabilną 1.5.2.
Później, każdorazowa aktualizacja będzie wymagała wykonanie polecenia lein upgrade.
$ lein help upgrade
Upgrade Leiningen to the latest stable release.
$ lein upgrade
The script at /Users/jacek/apps/bin/lein will be upgraded to the latest stable version.
Do you want to continue [Y/n]? Y
Upgrading...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8270 100 8270 0 0 4349 0 0:00:01 0:00:01 --:--:-- 55133
Downloading Leiningen now...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 9161k 100 9161k 0 0 566k 0 0:00:16 0:00:16 --:--:-- 620k
Now running Leiningen 1.6.1.1 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VMNa uwagę zasługuje również fakt uzupełnienia konfiguracji lein o instalację rlwrap, który pozwala na pracę w Clojure REPL, podobnie do linuksowej linii poleceń - historia, wyszukiwanie, edycja, itp. Więcej informacji można znaleźć na stronie Enhancing Clojure REPL with rlwrap.
Umieść rlwrap w zmiennej PATH, a lein skorzysta z niego.
$ rlwrap -v rlwrap 0.37 $ type rlwrap rlwrap is hashed (/opt/local/bin/rlwrap)
lein pozwala nam na utworzenie projektu (lein new), przygotowanie importu do IDE (lein pom), w którym korzysta się ze wsparcia dla projektów mavenowych, czy wykonaniu testów (lein test), uruchomieniu Clojure REPL (lein repl) i instalacji (lein install) oraz zbudowaniu projektu (lein jar). Dostępne polecenia poznasz wykonując polecenie lein help.
$ lein help Leiningen is a build tool for Clojure. Several tasks are available: classpath Print the classpath of the current project. clean Remove compiled class files from project. compile Compile Clojure source into .class files. deploy Build and deploy jar to remote repository. deps Download all dependencies and put them in :library-path. help Display a list of tasks or help for a given task. install Install the current project or download the project specified. interactive Enter interactive task shell. jar Package up all the project's files into a jar file. javac Compile Java source files. new Create a new project skeleton. plugin Manage user-level plugins. pom Write a pom.xml file to disk for Maven interop. repl Start a repl session either with the current project or standalone. retest Run only the test namespaces which failed last time around. run Run a -main function with optional command-line arguments. search Search remote repository contents. test Run the project's tests. test! Run a project's tests after cleaning and fetching dependencies. uberjar Package up the project files and deps into a jar file. upgrade Upgrade Leiningen to the latest stable release. version Print version for Leiningen and the current JVM. Run lein help $TASK for details. Also available: readme, tutorial, copying, sample, and news.
Tym samym mam narzędzie, które zniesie ze mnie konieczność zarządzania zależnościami projektowymi (a dokładniej zależnościami bezpośrednich zależności) i wystarczy zadeklarować wersję Clojure oraz Clojure Contrib, a reszta sprowadzi się do odpowiednich poleceń lein.
Przykładowa sesja z leiningen - utworzenie projektu i import do IDE
Rozpoczynamy projekt z lein przez wykonanie lein new z nazwą projektu, która opcjonalnie przyjmuje nazwę grupy, do której należy.
jacek:~/sandbox $ lein new pl.jaceklaskowski.clojure/witaj-clojure-gui Created new project in: /Users/jacek/sandbox/witaj-clojure-gui jacek:~/sandbox $ cd witaj-clojure-gui/ jacek:~/sandbox/witaj-clojure-gui $ ls -l total 24 -rw-r--r-- 1 jacek staff 176 May 14 18:05 README drwxr-xr-x 2 jacek staff 68 May 14 19:49 classes drwxr-xr-x 5 jacek staff 170 May 14 19:49 lib -rw-r--r-- 1 jacek staff 358 May 14 20:02 project.clj drwxr-xr-x 3 jacek staff 102 May 14 18:05 src drwxr-xr-x 3 jacek staff 102 May 14 18:05 test
Plikiem konfiguracji lein jest project.clj (który jest de facto aplikacją w Clojure).
Tworzymy konfigurację mavenową (a dokładniej generujemy plik pom.xml), aby IDE ze wsparciem dla tego typu projektów mogło zaimportować projekt i udostępnić środowisko graficzne do dalszej pracy programistycznej.
jacek:~/sandbox/witaj-clojure-gui $ lein pom Wrote pom.xml
Import do IDE i podniesienie wersji Clojure z Clojure Contrib to już chleb powszedni dla wielu pracujących z podobnymi narzędziami. Pozostawiam temat jako zadanie domowe (znużonych wieloma pracami domowymi uprasza się o kontakt z autorem).
Warto pamiętać, że każdorazowa zmiana zależności w project.clj wymaga ponownego utworzenia pom.xml (za pomocą lein pom) i odświeżenia projektu w IDE, np. w Eclipse z Counterclockwise wymaga to wciśnięcia klawisza F5.
Przykładowa sesja z Clojure REPL w wersji 1.3
Domyślnie, lein tworzy projekt z Clojure 1.2.1. Podniesienie wersji to aktualizacja project.clj z właściwą wersją Clojure.
(defproject clojure-sandbox "1.0.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.3.0"]
[org.clojure/clojure-contrib "1.3.0"]])Pamiętaj, aby dodać 1.3.0, a nie 1.3.
Uruchomienie lein repl w tym projekcie będzie już wykonane z Clojure 1.3.
jacek:~/sandbox/clojure-sandbox $ lein repl Downloading: org/clojure/clojure/1.3.0/clojure-1.3.0.pom from central Downloading: org/clojure/clojure/1.3.0/clojure-1.3.0.jar from central Copying 1 file to /Users/jacek/sandbox/clojure-sandbox/lib REPL started; server listening on localhost port 16122 user=> (clojure-version) "1.3.0"
Jeśli odpowiednia wersja Clojure nie będzie dostępna w lokalnym repozytorium, zostanie ściągnięta - dostęp do Sieci będzie w takim wypadku konieczny.
