web-dev-qa-db-ja.com

Mavenビルドで変更されたファイルのみ

私は以下のようなモジュール構造を持っているとしましょう

     Modules
       ->utils
       ->domain
       ->client
       ->services
       ->deploy (this is at the module level)

クライアントを起動するには、すべてのモジュールのビルドを作成する必要があります。i.e utils, domain, client, services,上記のすべてのモジュールのjarをロードして、クライアントを最終的にランチするためです。

そして、すべてのjarがモジュールdeployで組み立てられます。

私の質問は、たとえばサービスで何かを変更した場合、deploy mavenからビルドを実行するときに、servicesのみをビルドする必要があると認識できるため、ビルドしてdeployフォルダーにデプロイする方法がありますか? ?

30
user1224036

SVNと* nixを使用している場合、ルートモジュールから

mvn install -AMD -pl $(svn st | colrm 1 8 | sed 's /.*  ' | xargs echo | sed 's- -,:-g' | sed 's ^ : ') 
6
sebasjm

「clean」なしで「mvn install」のみを呼び出すと、コンパイラプラグインは変更されたクラスのみをコンパイルします。

25
Puce

マルチモジュールビルド内では、次を使用できます。

mvn -pl ChangedModule compile

ルートモジュールからは、指定されたChangedModuleのみがコンパイルされます。コンパイラプラグインは、変更されたファイルのみをコンパイルします。しかし、変更したモジュールがChangedModuleに依存している他のモジュールの再コンパイルを引き起こす可能性があります。これは、次を使用して実現できます。

mvn -AMD -pl ChangedModule compile

-AMDは依存関係も作成を意味します。 mvn installを使用して、モジュール全体をローカルリポジトリにインストールしなくても機能します。

12
khmarbaise

GITの場合

mvn install -AMD -pl $(git status | grep -E "modified:|deleted:|added:" | awk '{print $2}' | cut -f1 -d"/")

OR

。bashrcファイル内(.bashrcはホームディレクトリ〜/ .bashrcにあります。存在しない場合は作成します)、次の関数を追加します。

mvn_changed_modules(){
    [ -z "$1" ] && echo "Expected command : mvn_changed_modules (install/build/clean or any maven command)" && exit 0

        modules=$(git status | grep -E "modified:|deleted:|added:" | awk '{print $2}' | cut -f1 -d"/")

                if [  -z "$modules" ];
                then
                        echo "No changes (modified / deleted / added)  found"
                else
                        echo "Changed modules are : `echo $modules`"
                        mvn install -AMD -pl $modules
                fi
}


その後bashを再起動した後(コマンドプロンプト)、次のコマンドのみを使用できます ROOTディレクトリ自体から。

smilyface @ machine> MainDir] $ mvn_changed_module install


どのように機能しますか?
質問mvn install -AMD -pl servicesによると、「servicesモジュールでいくつかの変更が行われた」場合のコマンドです。そのため、最初に変更されたファイルからモジュール名を取得し、それをmvn-installコマンドの入力として配置します

例として、以下は変更されたファイルのリストです(git statusの出力)-
サービス/pom.xml
サービス/ReadMe.txt
web/src/Java/com/some/Name.Java
そして、serviceswebは、ビルド/コンパイル/インストールする必要があるモジュール名です。

5
smilyface

私も同じ不満を抱いており、その時点でプロジェクトを書きました-残念ながら、それは利用できませんが、似たようなものを実装した人々が見つかりました:

例- https://github.com/erickzanardo/maven-watcher

nodejsを使用し、mavenプロジェクトを想定していますが、WindowsとUNIXで同様に動作するはずです。

私の実装の考え方は、変更を監視し、変更をコンパイルすることです。 -nodemonのようなもの。

例えば

  • Javaファイルが変更された場合-モジュールをコンパイルします
  • クラスファイルまたはjarが変更された場合-他に何かを行います(たとえば、Tomcatの下でjarをコピーしてTomcatを再起動します)

そして、2つは無関係です.. Javaコンパイルが失敗した場合、jarファイルを更新する理由はないはずです。.それは非常に安定しています。

23Kのプロジェクトで使用しました.Javaファイルとそれはスムーズに動作しました。

監視プロセスの開始には数秒かかりましたが、変更が検出された場合にのみ実行されるため、全体的なエクスペリエンスは素晴らしいものでした。

追加しようとした次のステップは、SVNサポートに似ています-変更されたファイルをリストし、初期化として使用します。

重要なのは、コンパイルが失敗した場合、次の変更で再試行することです。したがって、複数のjarを変更していて、コードを記述している限りコンパイルが失敗した場合、正常にコンパイルされるまで、コードの変更ごとにすべてのコンパイルを再試行します。

古いプロジェクトを見つけたい場合は、少し修正して公開してください。

2
guy mograbi

前述のアドバイスを試して使用した後、次の問題に遭遇しました。

  1. Mavenのインストール(クリーンなし)にはまだ時間がかかり、いくつかのプロジェクトでは10〜20秒余分に時間がかかる場合があります。
  2. Sebasjmのソリューションは高速で便利です(数か月間使用していました)が、プロジェクトをいくつか変更している場合は、常にプロジェクトを再構築する(何も変更していなかったとしても)のは時間の無駄です

私にとって本当に効果的なのは、ソースの変更日とローカルリポジトリの.jarの変更を比較することです。また、VCSの変更されたファイルのみをチェックする場合(sebasjmの回答を参照)、日付の比較に顕著な時間はかかりません(私にとっては、100個の変更されたファイルに対して1秒未満でした)。このようなアプローチの主な利点は、実際に変更されたプロジェクトのみを非常に正確に再構築できることです。主な問題は、変更日比較を行うことで、1行のスクリプトよりも少し多くなります。

試してみたいが、私のバージョンを共有するようなスクリプトを書くのが面倒だという人のために: https://github.com/bugy/rebuilder (linux/windows)。それはいくつかの追加の有用なことを行うことができますが、主要なアイデアと中心的なアルゴリズムは上記で説明したとおりです。

2
buggy