ClojureのLeiningenの概要

  • link:/category/programming/ [プログラミング]

1. 前書き

  • Leiningenは、Clojureプロジェクトの最新のビルドシステムです。* Clojureで完全に記述および構成されています。

    Mavenと同様に機能し、実行する正確なステップを設定する必要なく、プロジェクトを説明する宣言的な設定を提供します。
    飛び込んで、Clojureプロジェクトを構築するためのLeiningenの使用方法を見てみましょう。

*2. Leiningen *のインストール

  • Leiningenはスタンドアロンのダウンロードとして入手できます*さまざまなシステム用の多数のhttps://github.com/technomancy/leiningen/wiki/Packaging[package managers]からもダウンロードできます。

    スタンドアロンのダウンロードは、https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat [Windows]およびhttps://raw.githubusercontent.com/technomancy/leiningen/stable/binで利用できます。 / lein [LinuxおよびMac]。 いずれの場合も、ファイルをダウンロードし、必要に応じて実行可能にすれば、すぐに使用できます。
    スクリプトが初めて実行されると、残りのLeingingenアプリケーションがダウンロードされ、それ以降はこれ以降キャッシュされます。
$ ./lein
Downloading Leiningen to /Users/user/.lein/self-installs/leiningen-2.8.3-standalone.jar now...
.....
Leiningen is a tool for working with Clojure projects.

Several tasks are available:
.....

Run `lein help $TASK` for details.

.....

3. 新しいプロジェクトの作成

  • Leiningenがインストールされると、_lein new _。*を呼び出して、それを使用して新しいプロジェクトを作成できます。

    これにより、一連のオプションから特定のテンプレートを使用してプロジェクトが作成されます。
  • app –アプリケーションの作成に使用

  • default –一般的なプロジェクト構造を作成するために使用されます。通常は
    図書館

  • plugin –ライニンゲンプラグインの作成に使用

  • template –将来の新しいLeingingenテンプレートの作成に使用
    プロジェクト

    たとえば、「my-project」という新しいアプリケーションを作成するには、次を実行します。
$ ./lein new app my-project
Generating a project called my-project based on the 'app' template.
これにより、以下を含むプロジェクトが作成されます。
  • ビルド定義– project.clj

  • 最初のソースファイルを含むソースディレクトリ– src _–
    – _src / my_project / core.clj

  • 初期テストファイルを含むテストディレクトリ– test
    test / my_project / core_test.clj

  • 追加のドキュメントファイル– README.md、LICENSE、
    CHANGELOG.md_および_doc / intro.md

    *ビルド定義の内部を見ると、ビルドの内容ではなく、ビルド方法が示されていることがわかります。*
(defproject my-project "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.9.0"]]
  :main ^:skip-aot my-project.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})
これは次のことを示しています。
  • プロジェクトの名前、バージョン、
    説明、ホームページ、ライセンスの詳細。

  • アプリケーションの実行時に使用するメイン名前空間

  • 依存関係のリスト

  • 出力を構築するターゲットパス

  • uberjarを構築するためのプロファイル

    メインのソース名前空間は_my-project.core_であり、__my_project / core.cljファイルにあります。 __Clojureでは、単一セグメントの名前空間を使用することはお勧めしません。これは、Javaプロジェクトのトップレベルクラスに相当します。
    さらに、JVMにはファイル名のハイフンに関する問題があるため、ファイル名はハイフンではなくアンダースコアで生成されます。
    生成されたコードは非常に簡単です。
(ns my-project.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))
*また、Clojureはここでは単なる依存関係であることに注意してください。 これにより、Clojureライブラリの任意のバージョンを使用してプロジェクトを作成するのが簡単になります*。特に、同じシステムで複数の異なるバージョンを実行することができます。
この依存関係を変更すると、代わりに代替バージョンが取得されます。

4. ビルドと実行

私たちのプロジェクトは、ビルド、実行、および配布用にパッケージ化できない場合、あまり価値がありません。次を見てみましょう。

* 4.1。 REPL *の起動

*プロジェクトを作成したら、_lein repl_ *を使用して、その内部でREPLを起動できます。 これにより、すべてのプロジェクトファイルとすべての依存関係を含む、プロジェクト内のすべてがクラスパスで既に利用可能なREPLが提供されます。
また、プロジェクト用に定義されたメイン名前空間で開始します。
$ lein repl
nREPL server started on port 62856 on host 127.0.0.1 - nrepl://127.0.0.1:62856
[]REPL-y 0.4.3, nREPL 0.5.3
Clojure 1.9.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_77-b03

    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

my-project.core=> (-main)
Hello, World!
nil
これは、上で見た現在の名前空間で関数_-main_を実行します。

* 4.2。 アプリケーションの実行*

アプリケーションプロジェクト(le_lein new app_を使用して作成)で作業している場合は、*コマンドラインからアプリケーションを実行するだけです。 これは、_lein run_ *を使用して実行されます。
$ lein run
Hello, World!
これにより、_project.clj_ファイルで_:main_として定義されているネームスペースで_-main_という関数が実行されます。

* 4.3。 ライブラリの構築*

ライブラリプロジェクト(_lein new default_を使用して作成)で作業している場合、*他のプロジェクトに含めるためにライブラリをJARファイルにビルドできます*。
これを実現するには、_lein jar_または_lein install_を使用する2つの方法があります。 違いは、出力JARファイルが配置される場所にあります。
  • _lein jar_を使用すると、ローカル_target_ディレクトリに配置されます*:

$ lein jar
Created /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar
  • lein install_を使用する場合、JARファイルをビルドし、_pom.xml_ファイルを生成してから、2つをローカルのMavenリポジトリに配置します*(通常、ユーザーのホームディレクトリの.m2 / repository_の下)

$ lein install
Created /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar
Wrote /Users/user/source/me/my-library/pom.xml
Installed jar and pom into local repo.

* 4.4。 Uberjar *の構築

アプリケーションプロジェクトに取り組んでいる場合、* Leiningenはuberjar *と呼ばれるものをビルドする機能を提供します。 これは、プロジェクト自体とすべての依存関係を含むJARファイルであり、そのまま実行できるように設定されています。
$ lein uberjar
Compiling my-project.core
Created /Users/user/source/me/my-project/target/uberjar/my-project-0.1.0-SNAPSHOT.jar
Created /Users/user/source/me/my-project/target/uberjar/my-project-0.1.0-SNAPSHOT-standalone.jar
ファイル_my-project-0.1.0-SNAPSHOT.jar_はローカルプロジェクトを正確に含むJARファイルであり、ファイル_my-project-0.1.0-SNAPSHOT-standalone.jar_はアプリケーションの実行に必要なすべてのものを含んでいます。
$ java -jar target/uberjar/my-project-0.1.0-SNAPSHOT-standalone.jar
Hello, World!

5. 依存関係

プロジェクトに必要なものはすべて自分で書くことができますが、他の人がすでに私たちに代わって行った作業を再利用する方が一般的にははるかに優れています。 これを行うには、プロジェクトをこれらの他のライブラリに依存させます。

* 5.1。 プロジェクトへの依存関係の追加*

*プロジェクトに依存関係を追加するには、_project.clj_ファイルにそれらを正しく追加する必要があります。*
依存関係は、問題の依存関係の名前とバージョンで構成されるベクトルとして表されます。 Clojure自体が依存関係として追加され、_ [org.clojure / clojure“ 1.9.0”] _の形式で記述されていることは既に確認しました。
他の依存関係を追加したい場合は、_:dependencies_キーワードの隣のベクトルに追加することで追加できます。 たとえば、_clj-json_に依存する場合、ファイルを更新します。
  :dependencies [[org.clojure/clojure "1.9.0"] [clj-json "0.5.3"]]
*完了後、REPLを開始する場合、またはプロジェクトをビルドまたは実行する他の方法を使用する場合、Leingingenは依存関係がダウンロードされ、クラスパスで利用できるようにします*:
$ lein repl
Retrieving clj-json/clj-json/0.5.3/clj-json-0.5.3.pom from clojars
Retrieving clj-json/clj-json/0.5.3/clj-json-0.5.3.jar from clojars
nREPL server started on port 62146 on host 127.0.0.1 - nrepl://127.0.0.1:62146
REPL-y 0.4.3, nREPL 0.5.3
Clojure 1.9.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_77-b03
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

my-project.core=> (require '(clj-json [core :as json]))
nil
my-project.core=> (json/generate-string {"foo" "bar"})
"{\"foo\":\"bar\"}"
my-project.core=>
プロジェクト内からも使用できます。 たとえば、生成された_src / my_project / core.clj_ファイルを次のように更新できます。
(ns my-project.core
  (:gen-class))

(require '(clj-json [core :as json]))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println (json/generate-string {"foo" "bar"})))
そして、それを実行すると、期待どおりに正確になります:
$ lein run
{"foo":"bar"}

* 5.2。 依存関係を見つける*

多くの場合、プロジェクトで使用する依存関係を見つけるのは困難です。 * Leingingenには、これを簡単にするための検索機能が組み込まれています*。 これは、_lein search_を使用して行われます。
たとえば、JSONライブラリを見つけることができます。
$ lein search json
Searching central ...
[com.jwebmp/json "0.63.0.60"]
[com.ufoscout.coreutils/json "3.7.4"]
[com.github.iarellano/json "20190129"]
.....
Searching clojars ...
[cheshire "5.8.1"]
  JSON and JSON SMILE encoding, fast.
[json-html "0.4.4"]
  Provide JSON and get a DOM node with a human representation of that JSON
[ring/ring-json "0.5.0-beta1"]
  Ring middleware for handling JSON
[clj-json "0.5.3"]
  Fast JSON encoding and decoding for Clojure via the Jackson library.
.....
*これにより、プロジェクトで使用しているすべてのリポジトリが検索されます*。この場合、Maven Centralとhttps://clojars.org/[Clojars]。 次に、正確な文字列を返してputproject.cljファイルに入れ、可能であればライブラリの説明を返します。

6. プロジェクトのテスト

  • Clojureは、アプリケーションの単体テストの組み込みサポートを備えており、Leiningenはこれをプロジェクトに利用できます。*

    生成されたプロジェクトには、_src_ディレクトリのソースコードとともに、_test_ディレクトリにテストコードが含まれています。 また、デフォルトでは、_test / my_project / core-test.clj_にある単一の失敗したテストが含まれています。
(ns my-project.core-test
  (:require [clojure.test :refer :all]
            [my-project.core :refer :all]))

(deftest a-test
  (testing "FIXME, I fail."
    (is (= 0 1))))
これにより、_my-project.core名前空間がプロジェクトからインポートされ、_ clojure.test名前空間がコアClojure言語からインポートされます。 次に、_deftest_および__testing __callsを使用してテストを定義します。
テストの名前と、テストが意図的に失敗するように書かれているという事実をすぐに確認できます。_0 == 1_であると断言します。
  • _lein test_コマンドを使用してこれを実行してみましょう。すぐに実行中および失敗したテストを確認してください。

$ lein test
lein test my-project.core-test

lein test :only my-project.core-test/a-test

FAIL in (a-test) (core_test.clj:7)
FIXME, I fail.
expected: (= 0 1)
  actual: (not (= 0 1))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
Tests failed.
代わりにテストを修正し、代わりに_1 == 1_をアサートするように変更すると、代わりに合格メッセージが表示されます。
$ lein test
lein test my-project.core-test

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
これははるかに簡潔な出力であり、知っておくべきことだけを示しています。 これは、*障害が発生するとすぐに目立つことを意味します*。
必要に応じて、テストの特定のサブセットを実行することもできます。 コマンドラインでは、名前空間を指定でき、その名前空間のテストのみが実行されます。
$ lein test my-project.core-test

lein test my-project.core-test

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

$ lein test my-project.unknown

lein test my-project.unknown

Ran 0 tests containing 0 assertions.
0 failures, 0 errors.

7. 概要

この記事では、Leiningenビルドツールの使用方法と、それを使用してClojureベースのプロジェクト(実行可能アプリケーションと共有ライブラリの両方)を管理する方法を示しました。
次のプロジェクトで試してみて、どれだけうまく機能するか見てみましょう。