Leiningen

Leiningen - fxjwind - 博客園
http://www.cnblogs.com/fxjwind/archive/2013/03/07/2948005.html

https://github.com/technomancy/leiningen

1 What's Leiningen
Leiningen is a tool for automating Clojure projects without setting your hair on fire.
If you come from the Java world, Leiningen is "Maven meets Ant without the pain". For Ruby and Python folks, Leiningen combines RubyGems/Bundler/Rake and pip/Fabric in a single tool.
Clojure項(xiàng)目自動(dòng)化創(chuàng)建, 編譯, 打包和部署的工具集. 具體可以提供如下功能,
It manages various project-related tasks, and can:
create new projects
manage dependencies for your project
run tests
run a REPL (without you having to worry about adding dependencies to the classpath)
compile Java sources (if any)
run the project (if the project is an app)
generate a maven-style "pom" file for the project
compile and package projects for deployment
publish libraries to maven artifact repositories such as Clojars
run custom automation tasks written in Clojure (leiningen plug-ins)

2 Basic Usage
help, 幫助手冊
Use lein help
to see a complete list. lein help $TASK
shows the usage for a specific task.
new, 創(chuàng)建新項(xiàng)目
$ lein new [TEMPLATE] NAME # generate a new project skeleton

run, 執(zhí)行, 以-main函數(shù)會(huì)入口函數(shù)

****$ lein run -m my.namespace # run the -main function of a namespace

test, 執(zhí)行test namespace目錄里面的所有testcase

$ lein test [TESTS] # run the tests in the TESTS namespaces, or all tests

repl, launch repl
****$ lein repl # launch an interactive REPL session

uberjar, 將project打包成jar
****$ lein uberjar # package the project and dependencies as standalone jar

串聯(lián)執(zhí)行
You can also chain tasks together in a single command by using the do
task with comma-separated tasks:
$ lein do clean, test foo.test-core, jar

在project directory內(nèi)執(zhí)行命令
Most tasks need to be run from somewhere inside a project directory to work, but some (new
, help
, search
, version
, andrepl
) may run from anywhere.

3 Create Project
使用lein new來創(chuàng)建新的clojure項(xiàng)目, 會(huì)在當(dāng)前目錄創(chuàng)建項(xiàng)目目錄my-stuff.
$ lein new my-stuffGenerating a project called my-stuff based on the 'default' template.$ cd my-stuff$ find .../.gitignore./doc./doc/intro.md./project.clj./README.md./src./src/my_stuff./src/my_stuff/core.clj./test./test/my_stuff./test/my_stuff/core_test.clj

Namespace Mapping Convention
創(chuàng)建project時(shí), 會(huì)自動(dòng)創(chuàng)建namespace my-stuff.core
my-stuff.core
instead of just my-stuff
since single-segment namespaces are discouraged in Clojure. Namespace在FP里面比較重要, 比在OO里面重要, 因?yàn)閷?duì)于OO還有class, 其實(shí)就是做了一層的namespace封裝, 有效的避免沖突 但是對(duì)于FP, 直接就是function, 如果不加合理的namespace, 那就太容易沖突了 所以這兒使用my-stuff.core, 在project內(nèi)部需要namespace的分層, 除了core, 肯定應(yīng)該有其他的子namespace……

4 Project.clj, Configuration
首先可以看出data=code, 配置文件一樣可以用clojure文件來寫, 只要實(shí)現(xiàn)macro, 配置文件直接就可以run, 很牛!
Default自動(dòng)生成的project.clj的模板如下:
(defproject my-stuff "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.4.0"]])
一個(gè)簡單的例子,
(defproject myproject "0.5.0-SNAPSHOT" :description "A project for doing things." :license "Eclipse Public License 1.0" :url "http://github.com/technomancy/myproject" :dependencies [[org.clojure/clojure "1.4.0"]] :plugins [[lein-ring "0.4.5"]])
實(shí)際使用的會(huì)比這個(gè)復(fù)雜很多, 參考下面的sample.project.clj
See the sample.project.clj file (also available via lein help sample
) for a detailed listing of configuration options.
通過profiles可以根據(jù)不同的情況設(shè)定不同的configuration
The project.clj
file can be customized further with the use of profiles.

Dependencies
Overview
Clojure is a hosted language and Clojure libraries are distributed the same way as in other JVM languages: as JARs.
JARs (.jar
files) are basically just .zip
files with a little extra JVM-specific metadata. They usually contain .class
files (JVM bytecode) and .clj
source files, but they can also contain other things like config files, JavaScript files or text files with static data.
必須要指明, project和其他包的依賴關(guān)系, 這樣leiningen才能自動(dòng)的下載配置相關(guān)包, 以保證project可以被正常的編譯和運(yùn)行.


Artifact IDs, Groups, and Versions
Artifact IDs, 包的名字, 如clojure, hibernate Groups, 一般是reversed域名, 如com.cedarsoft.utils.legacy Versions, 版本號(hào), 1.3.4 [com.cedarsoft.utils.legacy/hibernate "1.3.4"]

Clojure libraries often use the same group-id and artifact-id (as with clj-http), in which case you can omit the group-id.
[clj-http "0.5.5"]

Snapshot Versions
Sometimes versions will end in "-SNAPSHOT". This means that it is not an official release but a development build.
所以自動(dòng)生成的project.clj的版本是帶"-SNAPSHOT": my-stuff "0.1.0-SNAPSHOT"
當(dāng)然盡量不要在dependency里面加snapshot的版本, 除了你知道你在干嗎, 并確實(shí)需要這樣... 另外的原因是對(duì)于snapshot version, leiningen每天都會(huì)去更新最新版, 所以有效率問題...
Adding a snapshot dependency to your project will cause Leiningen to actively go seek out the latest version of the dependency daily (whereas normal release versions are cached in the local repository) so if you have a lot of snapshots it will slow things down.

Artifact IDs, Groups和Namespace的關(guān)系
Note that some libraries make their group-id and artifact-id correspond with the namespace they provide inside the jar, but this is just a convention. There is no guarantee they will match up at all.

Repositories
Dependencies are stored in a maven repository (類似PyPi)
There are several popular open source repositories. Leiningen by default will use two of them: clojars.org and Maven Central.
leiningen需要根據(jù)配置的dependency, 來自動(dòng)的找到這些包, 去哪兒找, 默認(rèn)是clojars.org and Maven Central
可以自行增加third-party repositories You can add third-party repositories by setting the :repositories
key in project.clj. See the sample.project.clj.

5 Running Code
Lein REPL
The REPL is an interactive prompt where you can enter arbitrary code to run in the context of your project.
lein repl和一般的repl相比, 最大的優(yōu)勢是, project context awareness 對(duì)于一般的repl, 能夠被require的包都必須要在classpath底下能夠找到, 如果沒有, 你需要自己去download并配置到classpath里面去 而lein會(huì)自動(dòng)的管理dependency, 只需要在project.clj里面把需要的denpendency寫清楚, lein會(huì)自動(dòng)完成download和classpath配置 所以只需要在project目錄下執(zhí)行l(wèi)ein repl, 即可以require當(dāng)前project namespace的所有代碼, 以及所有denpendency的庫 這個(gè)相當(dāng)方便, 尤其在測試的時(shí)候
需要注意的是, lein repl其實(shí)是可以在任何目錄下執(zhí)行的, 但是如果不是project目錄, 那就和普通repl沒有任何區(qū)別.

Lein REPL還有命令提示, 主要有如下命令
函數(shù)執(zhí)行
user=> (require 'my-stuff.core)niluser=> (my-stuff.core/foo “me”)me Hello, World!nil

如果在denpendency中加了[clj-http "0.5.5"]
user=> (require '[clj-http.client :as http])niluser=> (def response (http/get "http://leiningen.org"))#'user/response

幫助文檔, doc, javadoc, clojuredocs

doc, find-doc顯示幫助文檔 javadoc, 顯示java的幫助文檔
clojuredocs
offers more thorough examples from the ClojureDocs site.
ClojureDocs is a community-powered documentation and examples repository for the Clojure programming language.

clojuredocs這個(gè)挺管用, 比如你不知道reduce怎么用

user=> (user/clojuredocs reduce)

就會(huì)給出很多例子, 也可以直接去網(wǎng)站查, 更好看些, http://clojuredocs.org/clojure_core/clojure.core/reduce
查看源代碼, source
user=> (source my-stuff.core/foo)(defn foo "I don't do a whole lot." [x] (println x "Hello, World!"))nil

Lein Run
如果要使用lein run去運(yùn)行namespace, 必須先實(shí)現(xiàn)-main函數(shù), 因?yàn)閘ein run -m會(huì)在namespace里面找-main, 如果沒有, 會(huì)報(bào)錯(cuò)
(defn -main "I don't do a whole lot." [& args] (println "Hello, World!"))

$ lein run -m my-stuff.coreHello, World!

Providing an alternate -m
argument will tell Leiningen to look for the -main
function in another namespace. Setting a default :main
in project.clj
lets you omit -m
. 比如加上如下配置,
:main my-stuff.core

可以直接運(yùn)行, 不用-m $ lein run Hello, World!

6 Tests
We haven't written any tests yet, but we can run the failing tests included from the project template:
$ lein testlein test my.test.stuffFAIL in (a-test) (stuff.clj:7)FIXME, I fail.expected: (= 0 1) actual: (not (= 0 1))Ran 1 tests containing 1 assertions.1 failures, 0 errors.

Once we fill it in the test suite will become more useful. Sometimes if you've got a large test suite you'll want to run just one or two namespaces at a time; lein test my.test.stuff
will do that. You also might want to break up your tests using test selectors; see lein help test
for more details.

7 Make Jar
Generally speaking, there are three different goals that are typical of Leiningen projects:
An application you can distribute to end-users
A library for other Clojure projects to consume
A server-side application

Uberjar
The simplest thing to do is to distribute an uberjar. This is a single standalone executable jar file most suitable for giving to nontechnical users. 最簡單的方式, 直接打包成可執(zhí)行的jar

  1. 在project.clj加上:main, 配置-main存在的namespace
  2. 在namespace聲明中, 加上:gen-class. 不加會(huì)報(bào)錯(cuò)(Error: Could not find or load main class my_stuff.core)
    (ns my-stuff.core (:gen-class))3. Generate your uberjar. 會(huì)生成兩個(gè)jar, standalone版本是包含所有依賴包的

$ lein uberjarCompiling my.stuffCompilation succeeded.Created /home/phil/src/leiningen/my-stuff/target/my-stuff-0.1.0-SNAPSHOT.jarIncluding my-stuff-0.1.0-SNAPSHOT.jarIncluding clj-http-0.4.1.jarIncluding clojure-1.3.0.jarIncluding lucene-core-3.0.2.jarCreated /home/phil/src/leiningen/my-stuff/target/my-stuff-0.1.0-SNAPSHOT-standalone.jar

  1. 象普通jar一樣的執(zhí)行
    $ java -jar my-stuff-0.1.0-standalone.jar Hello world.Welcome to my project! These are your args: (Hello world.)

Framework (Uber)jars
看下面的例子, 對(duì)于hadoop這樣framework的包, 無法也無需打包到j(luò)ar里面 因?yàn)楸仨殞?shí)際的運(yùn)行環(huán)境里面有hadoop集群否則, 根本運(yùn)行不了 所以使用:provided, 表示需要, 但是不包含在jar里面, 需要使用者保證運(yùn)行環(huán)境符合.
(project example.hadoop "0.1.0" ... :profiles {:provided {:dependencies [[org.apache.hadoop/hadoop-core "0.20.2-dev"]]}} :main example.hadoop)

Server-side Projects
There are many ways to get your project deployed as a server-side application. Aside from the obvious uberjar approach, simple programs can be packaged up as tarballs with accompanied shell scripts using the lein-tar plugin and then deployed using pallet, chef, or other mechanisms.

Publishing Libraries
If your project is a library and you would like others to be able to use it as a dependency in their projects, you will need to get it into a public repository.
可以將生成的jar發(fā)布到public庫里面
$ lein deploy clojars

8 Getting Started with Eclipse and Counterclockwise
Eclipse的leiningen插件, 使用更方便
http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise

ctrl+alt+s, 執(zhí)行當(dāng)前cljr文件, 并啟動(dòng)repl

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末巷帝,一起剝皮案震驚了整個(gè)濱河市旁趟,隨后出現(xiàn)的幾起案子洁灵,更是在濱河造成了極大的恐慌,老刑警劉巖垦江,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡屿脐,警方通過查閱死者的電腦和手機(jī)挺益,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門歉糜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人望众,你說我怎么就攤上這事匪补。” “怎么了烂翰?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵夯缺,是天一觀的道長。 經(jīng)常有香客問我甘耿,道長踊兜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任佳恬,我火速辦了婚禮捏境,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殿怜。我一直安慰自己典蝌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布头谜。 她就那樣靜靜地躺著骏掀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柱告。 梳的紋絲不亂的頭發(fā)上截驮,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音际度,去河邊找鬼葵袭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛乖菱,可吹牛的內(nèi)容都是我干的坡锡。 我是一名探鬼主播蓬网,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鹉勒!你這毒婦竟也來了帆锋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤禽额,失蹤者是張志新(化名)和其女友劉穎锯厢,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脯倒,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡实辑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藻丢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剪撬。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖郁岩,靈堂內(nèi)的尸體忽然破棺而出婿奔,到底是詐尸還是另有隱情,我是刑警寧澤问慎,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布萍摊,位于F島的核電站,受9級(jí)特大地震影響如叼,放射性物質(zhì)發(fā)生泄漏冰木。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一笼恰、第九天 我趴在偏房一處隱蔽的房頂上張望踊沸。 院中可真熱鬧,春花似錦社证、人聲如沸逼龟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腺律。三九已至,卻和暖如春宜肉,著一層夾襖步出監(jiān)牢的瞬間匀钧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工谬返, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留之斯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓遣铝,卻偏偏與公主長得像佑刷,于是被迫代替她去往敵國和親莉擒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容