Gradleと自動化の解決

みなさんこんにちは、今日はマニュアルを書き直しているだけでなく(書かれていますが)、Gradleでの私の経験についてお話ししたいだけでなく、私が遭遇した実際の問題とそれらを獲得した方法を教えてください。 このトピックは非常に広範囲に及ぶため、残念ながら、多くの側面を詳細に一貫して検討することはできません。読者が既にGradleに少し精通しており、説明されているソリューションの本質を理解できることを願っています。



歌詞


Mavenに関する重要な注意点は、以前にMavenでGradleを使用して行った多くのタスクを実行しようとしたことがないため、良くも悪くも多くのものを比較できないことです。



最初に気に入ったのは「さようならxml」でした。そうです、私にとっては本当に生まれ変わったようなものです。実際のプログラミング言語でアセンブリを作成するのは本当に素晴らしかったです。それは自由とインスピレーションです。



この記事では、OSGIとeclipse rcpのいくつかの概念を使用しますが、メイントピックから気が散らないように、それらに焦点を当てません。



このアプリケーションには、スクリプトの例と記事で使用されているいくつかのソースコードを含む単純なプロジェクトがあります。



問題規模


だから、私たちが最初に持っていたもの:OSGIプラットフォームで実行されている大規模な(私の標準による)システムがあり、システム内のプロジェクトはEclipseプラグインプロジェクトであり、ビルドシステムとの統合はなく、antはビルドシステムとして使用され、依存関係制御システムなかった。 すべてをクールにするタスクがありました。



だから私はGradleを提案し、彼らは私にゴーサインを与え、それが始まりました。



プロジェクト構造の説明


問題の本質は、プロジェクトが保存される特定の構造を持つディレクトリがあることです。

最初にすることは、ビルドスクリプトでディレクトリ構造と使用可能なすべてのプロジェクトを記述することでした。 簡単にできました。 Gradleは、このためにマルチプロジェクトの概念を使用しています。 ルートディレクトリでsettings.gradleファイルを作成し、プロジェクトがパス区切り文字「:」で区切られている各フォルダーへのパスを書き込みます。 Settings.gradleの例:



include "subproject-first" include "subproject-first:child-first" include "subproject-first:child-first:another-child:last-child" include "subproject-first:child-first:another-child:another-last-child" include "subproject-second"
      
      







次のコマンドを実行して、システムの構造を確認できます。



 gradle projects -q
      
      







結果:



画像



IDEセットアップ


次のステップは、プロジェクトをIDEにインポートする機能でした。 Gradleには、アイデアと日食用のプラグインがあります。

tynts

バラビネッツ



私たちのプロジェクトは、osgiと、ターゲットプラットフォームを取得することができなかったeclipse-rcpのおかげで、Eclipseと非常に密接に結びついています(これは、osgiの世界からは本当にひどいことです。実際には、osgiフレームワークとjarニックネームの束を持つフォルダーです)そのアイデアですが、一般的には叙情的な余談です。



Eclipseプラグインを使用して、必要に応じてプロジェクトを構成できましたが、プロジェクトをEclipseプラグインとして作成し、設定でプラグインの依存関係を登録し、使用するコンパイラーのバージョンを指定する必要がありました。 設定例:



 project.apply plugin: 'java' project.apply plugin: 'eclipse' project.apply plugin: 'idea' project.eclipse { jdt { sourceCompatibility = '1.6' } project { //     eclipse plug-in natures 'org.eclipse.pde.PluginNature' } classpath { downloadSources = true downloadJavadoc = true // java se 1.6 jre containers.clear() containers.add("org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6") file { //  .classpath  plugin-dependencies  (      —     osgi  ) withXml { Node node = it.asNode() node.appendNode('classpathentry', [kind: 'con', path: 'org.eclipse.pde.core.requiredPlugins']) } } } }
      
      







つまり、ご覧のとおり、Eclipseには多くの設定がありますが、Eclipse APIプラグインではできないことは、xml設定ファイルを修正することで手動で行うことができます。



依存関係


次のステップ、依存関係管理: ドキュメント



Mavenには依存関係の管理に勝るものはないと考えていましたが、今は間違っていたと思います。 Gradleは、maven、ivy、および単純なフォルダーとファイルの依存関係を使用できます。一般に、必要に応じて、非常に標準的ではない操作を実行できます。たとえば、ftpサーバーをリポジトリとして使用できます。 たとえば、依存関係の記述方法:



 project(":myproject") { dependencies { //    compile project(":other-my-project") //     compile fileTree(dir: "libs", include: "*.jar") //   maven  compile 'org.hibernate:hibernate-core:3.6.3.Final' } }
      
      







しかし、これはほんの始まりに過ぎません。 Gradleには構成の概念があります。これは、依存関係が追加されるグループに似ています。 つまり、コンパイル例では、これはjavaプラグインが作成する構成です。



この機会は、依存関係に関する1つの問題を美しく解決するのに役立ちました。この問題の本質はこれです:私たちのカーネルは海外で開発されており、結果はzipアーカイブの形で私たちに届きます。その中には、必要なライブラリのセットを含む多くの異なるファイルがあります このアーカイブは、外部の力によってアーティファクトに注ぎ込まれます。次に、アーティファクトから取得し、一時ディレクトリに保存し、解凍し、解凍したフォルダから必要なライブラリをすべて取り出します。



アーカイブをダウンロードして解凍します。



 //   temp      File sdkDir = getSdkDir(sdkVersion) //    project.configurations { sdk libsFromSdk } // artifactory       project.repositories { maven { url 'http://localrepo:8081/artifactory/repo' } mavenCentral() mavenLocal() } //  project.dependencies { sdk group: 'com.kontora', name: 'sdk', version: sdkVersion, ext: 'zip' } Configuration cfg = project.configurations.sdk // zip    cfg.files.each { File zipArchive -> //    project.ant.unzip src: zipArchive, dest: sdkDir.absolutePath }
      
      







アクションのセット全体は、アセンブリに関してGradle言語のddleを使用してプログラムされることに注意してください。 プログラミング言語で低レベルのコードを書く必要はありません。



展開されたアーカイブからプロジェクトへの依存関係の接続:



 project.dependencies { libsFromSdk project.fileTree(dir: "$pathToSdk/libs", include: "*.jar") … //    libsFromSdk  compile  project.compile libsFromSdk }
      
      







そして最後に、コンパイルのためにすべての依存関係を取得します。



私はあなた自身が新しいコードではないコードを愛しています


一方、スクリプトはどんどん大きくなります。 コピーアンドペーストコードの重複の問題について考えてみましょう。 ソフトウェアシステムがあり、システム内のコードの複製が悪いことを全員が理解していると仮定しますが、何らかの理由でビルドシステムの設定内のテキスト行の複製は何か問題があるとは見なされません。 xmlは基本的に構成ファイルであり、構成ファイルにプログラミング規則を適用することは完全に正しいわけではないため、この理由はxmlでのアセンブリの説明だと思います。 しかし同時に、何百ものファイルに同じ構成テキストを書くことは完全に美しいわけではなく、プログラマーが方向を定めるのが難しく、アセンブリエラーを暗黙的かつ困難に検出する可能性があります。 Gradleでは、アセンブリのコードを記述すると、通常のコードの場合と同様に、標準的な方法でアセンブリシステムの構成コードの重複を取り除くことができます。 そして、ここでGradleは再びその力と美しさを示しました。



トライアム



いくつかの調査の後、最初のプラグインを作成しました。 システムのルートフォルダーにbuildSrcフォルダーを作成できます。これは、選択したjava、groovy、scalaなどのプロジェクトになります。ビルドシステムが起動すると、buildSrcプロジェクトが最初にコンパイルされ、このプロジェクトのクラスがビルドスクリプトで使用できます。 私にとっては素晴らしいです。



その結果、たとえば、buildSrcのクラス内の1か所にのみ記述されたプロジェクトへの名前とパスがあり、他のすべてのスクリプトはプロジェクト名が格納されているこれらの変数を使用します(もちろん、このアプローチの長所と短所については別の会話です)自動コード補完があります。アセンブリのどこかにMyProjects.subproject.child.absolutePathのように記述します。 さらに、ほとんどのビルドロジックは同じbuildSrcのプラグインにあります。

ビルドスクリプトでのプラグインとその呼び出しの例を次に示します。



プラグインの例:

 package org.gradle.example import org.gradle.api.Project import org.gradle.api.Plugin class MyPlugin implements Plugin<Project>{ private static final String PLUGIN_EXTENSION = 'my' Project project; @Override public void apply(Project project) { MyPlugin plugin = project.extensions.create(PLUGIN_EXTENSION, MyPlugin.class) plugin.project = project; } public void applyCommonSettings() { project.apply plugin: 'java' project.apply plugin: 'eclipse' project.apply plugin: 'idea' } }
      
      







プラグインを呼び出す例:

 project.apply plugin: MyPlugin my{ applyCommonSettings() }
      
      







真珠のボタンでもまったく同じですか?


Gradleプラグインに移ります。システムには異なる構造と設定を持つ異なるプロジェクトがあります。これらはjava、flex、androidプロジェクトです。 そして、このすべての経済は、IDEへのエクスポートのために別々に構成する必要があります。 たとえば、私たちが持っているプロジェクトのほとんどはOsgiプロジェクトであり、他の部分は単純なプロジェクトです。一部のプロジェクトはレガシー構造(つまり、srcフォルダーのみ)を持っています。 そして、Gradleはこのタスクに簡単に対処できるようにしました。 使用できる設定を示すクラスをいくつか作成し、各プロジェクトのすべての設定を説明するファクトリクラスを作成し、プロジェクトをideにインポートすると、これらの設定を取得して適用します。 これは通常のロジックを備えた単なるグルーヴィーなコードであるため、ここではコードの例を示しません。



また、プロジェクトの構造を検証する独自のバリデーターを作成できました。



また、あらゆる種類のクールなものがたくさん計画されています。 残念ながら、gradleプラグインのユニットテストの作成、ロギング機能などについて話す時間はありません。



おわりに


Gredlに非常に満足しています。これは101%の成果を上げており、このシステムを使用する喜びを知ってほしいと思います。



All Articles