MPS 2019.2ヘルプ

ビルド言語

MPSビルド言語とは何ですか?

ビルド言語は宣言的な方法でビルドを定義するための拡張可能なビルド自動化DSLです。Ant(英語)に生成された、Antの実行機能を活用しながら、ソースをクリーンで無駄のない詳細情報から解放します。一番下にANTがあるMPS言語のスタックとして編成されているため、ビルド手順の各部分を異なる抽象化レベルで表現することができます。(MPSプラグインのような)複雑なアーティファクトを構築することは、言語の慣習に従えば、たった1行のコードで指定できますが、同時に、ファイル管理や詳細のカスタマイズを妨げるものは何もありません。マニフェストプロパティー

多くのビルド自動化ツールと同様に、プロジェクト定義はスクリプトの中核です。さらに、他のほとんどのツールとは異なり、ビルド言語では出力ディレクトリーのレイアウトを完全に制御できます。予想されるビルド結果はビルドスクリプトで別々に定義され、(サードパーティの)プラグインの一部としては定義されません。
すべてのビルドスクリプトは3つの部分から構成されています。1つは依存関係です。これはすでに構築されているために必要なものです。たとえば、ライブラリーやサードパーティの言語を考えてください。次はプロジェクトの構成です。これにはあなたのリポジトリにあるものすべて、これからビルドされるもの、必要なビルドパラメータの宣言が含まれています。ここで項目を宣言しても、それが必要でない限り、つまりスクリプトの最後の部分( 出力レイアウト)から参照されていない限り、ビルドは開始されません。出力は、普通のフォルダーやコピーしたファイルのセットと同じくらい簡単なものでも、パッケージ化されたプラグインやMPS言語などのzipされたアーティファクトを含む複雑なものでも構いません。例:Javaソースからjarファイルを構築するには、プロジェクト構造内のJavaモジュールと、出力レイアウト内のモジュールへの参照を含むそれぞれのjarファイルを宣言する必要があります。

MPSのおかげで、ビルド言語は簡潔なテキスト表記法と、完成とその場での検証を含む優れた編集経験を持っています。拡張言語(または他のビルドツールの用語を使用している場合はプラグイン)により、言語の上位に抽象化が追加されます。私たちの経験では、MavenやGradleプラグインを開発するのに比べて、新しいものを作成するのはとても簡単なプロセスです。

スクリプト構造を構築する

以下のIntellij IDEA用のプラグインをビルドするビルドスクリプトの例を参照してください。

samplesScript

それをよく見てみましょう。スクリプトのヘッダーは、一般的なスクリプト情報から構成されています。スクリプトの名前(スクリーンショットの複合)、それが生成されたファイル(build.xml)、およびスクリプトのベースディレクトリー(スクリーンショットの1つでは相対的です)スクリプトの場所../../とフルパス)。

スクリプトの本体は、以下のセクションで構成されています。

  • use pluginsには、スクリプトで使用されているプラグインのリストが含まれています。ビルド言語のプラグインはGradleのプラグインと似ています。javaコードのコンパイル、単体テストの実行、パッケージ化モジュールなどの便利なことを行うための多数のタスクを提供する言語の拡張です。スクリーンショットでは2つのプラグインが使用されます。javamps、つまりスクリプトはjavaとmpsのコードを構築できます。

  • macrosセクションは、プロジェクトで使用されるパスマクロと変数( idea_homeplugins_home )をそれらのデフォルト値と一緒に定義します。これはスクリプトの実行中にオーバーライドされる可能性があります。

  • 依存関係は、他のビルドスクリプトに対するスクリプトの依存関係を定義します。スクリプトが他のビルドスクリプトで定義されたものを参照する場合、依存関係セクションでこのスクリプトを指定する必要があります。スクリーンショットのスクリプト例は、他の2つのスクリプトIDEAおよび mpsPlugin に依存しています。これらはMPSによって提供されるため、使用するには、アーティファクトの場所、つまりantが作業の結果を見つけることができる場所を指定する必要があります。(例では、 idea_home はIntellij IDEA jarの場所を指し、 plugins_home はIDEAのMPSプラグインの場所を指します。同じMPSプロジェクトのいくつかのビルドスクリプトに依存することもできます。その場合、アーティファクトの場所は不要であり、必要なスクリプトは現在のスクリプトの直前に構築されると想定されます(そうするためのターゲット buildDependents があります)。

  • プロジェクト構造セクションには、プロジェクトの説明、つまりどのモジュールがあるか、ソースコードの場所、モジュールのクラスパスなどが含まれています。スクリーンショットのサンプルプロジェクトは、複合という名前の単一のアイデアプラグインとそのグループです。MPSモジュール

  • デフォルトレイアウトは、プロジェクトをディストリビューションにパッケージ化する方法を定義します。スクリーンショットのサンプルプロジェクトは、Complex.zipという名前のzipファイルにパッケージ化されています。

  • その他の側面では、プロジェクトに関連するその他の事項(さまざまな設定、実行する統合テストなど)を定義します。

マクロ

マクロには2種類あります。

  • フォルダー - ファイルシステム内の物理フォルダーを表します。空のままにすると( デフォルト )、値はMPSで定義された同じ名前のパス変数から取得されます。

  • 変数 - 値を表すカスタム変数

変数は、いくつかの方法で初期化できます。

  • 以前のマクロへの参照

  • date - 日付値、Javaの日付フォーマット規則に従うパターンパラメータを指定する必要があります。たとえば、yyyy-MM-dd。ビルドスクリプトが実行された時刻の日付値がマクロに挿入されます。

  • ファイルからロード - 指定されたプロパティーファイルから指定されたプロパティー値を読み込みます

  • text - プレーンテキスト値

組み込みプラグイン

ビルド言語はいくつかの組み込みプラグインを提供します。

Javaプラグイン

Javaプラグインはjavaコードをコンパイルしてパッケージ化する機能を追加します。ソースコードはjavaモジュールとjavaライブラリーとして表されます。

Javaモジュールは、その内容(ソースフォルダーの場所)と他のモジュール、ライブラリー、およびjarへの依存関係を定義します: コンテンツセクションでjavaモジュールは持つことができます:

  • folder - ディスク上のソースフォルダーへのパス。

  • resources - リソースのファイルセット。( 含ま 除外または含まれる )、リソースフォルダーのパスとセレクタのリストで構成されます。

  • コンテンツ・ルート - 複数のコンテンツフォルダーを持つルート。

依存関係セクションでjavaモジュールは持つことができます:

  • classpath - クラスパスを持つ任意のxml。

  • 外部jar - 他のビルドスクリプトレイアウトからのjarファイル。

  • フォルダー内の外部jar - 他のビルドスクリプトレイアウトからフォルダー内の名前で参照されるjarファイル。

  • jar - ローカルjarへのパス。

  • library - javaライブラリーへの参照。

  • module - javaモジュールへの参照

各javaモジュールは、ソースモジュールの依存関係に従って他のターゲットに依存する独自のantターゲットに生成されます。循環モジュールの依存関係をコンパイルするために、2段階のコンパイルが実行されます。

  1. 「サイクル」ターゲットは、サイクル内のすべてのモジュールをまとめてコンパイルします。

  2. サイクル内の各モジュールは、クラスパス内の "cycle" ターゲットのコンパイル結果でコンパイルされます。

Javaライブラリーはjar(パスまたは他のプロジェクトレイアウトへの参照として指定される)とクラスフォルダーで構成されています。利用可能な要素は以下のとおりです。

  • classesフォルダー - クラスを含むフォルダー。

  • 外部jar - 他のビルドスクリプトレイアウトからのjarファイル。

  • 外部jar from - 他のbuilsスクリプトレイアウトのフォルダーからのjarのコレクション。

  • jar - ローカルjarへのパス。

  • jars - jarを含むローカルフォルダーへのパスとセレクタのリスト( includeexclude、またはincludes )。

javaモジュールのコンパイル設定は、javaオプションで指定されています。ビルドスクリプトにはjavaのオプションがいくつかありますが、そのうちの1つだけをデフォルトにすることができます。各モジュールはコンパイルに使用される独自のjavaオプションを指定できます。

Javaターゲット

Javaプラグインは以下のターゲットを追加します。

  • compileJavaはプロジェクト内のすべてのjavaモジュールをコンパイルします。

  • 追加のリソース処理のためのprocessResources拡張ポイント。

  • クラスは、プロジェクト内のすべてのコンパイルとリソース処理を行います。ターゲットcompileJavaprocessResourcesに依存します

  • ユニットテストを実行するためのテスト拡張ポイントターゲット。

  • checkはすべてのテストとプロジェクトの正当性のチェックを行います。ターゲットテストによって異なります。

MPSプラグイン

MPSプラグインを使用すると、スクリプト内のビルド言語でmpsモジュールをビルドできます。MPSプラグインを使用するには、jetbrains.mps.build.mps言語を使用言語に追加する必要があります。

MPSモジュールとグループ

MPSプラグインはプロジェクト構造にモジュールを追加することを可能にします。スクリーンショットには、ビルドスクリプトで宣言された言語の例があります。

sampleLanguage

ビルドスクリプトで指定されたモジュールに関する多くの情報があることに注意してください。それらのほとんどはインスペクタツールウィンドウに表示されます: uuid完全修飾名、記述子ファイルへのフルパス依存関係ランタイム (言語用)など。モジュールの梱包にはが必要です。依存関係が追加されるなど、このモジュールのために何かが変わるたびに、ビルドスクリプトも変更されなければなりません。もちろんそれを簡単にするためのツールはたくさんあります。スクリプトでmpsモジュールを作成し管理する典型的なプロセスは次のようになります。

  1. スクリプトにモジュールを追加します。追加するモジュールの種類(ソリューション、言語、またはdevkit)とモジュール記述子ファイルへのパスを指定します。それからインテンション "ファイルから必要な情報を読み込む"を使ってそのファイルを読み、残りのモジュール仕様を自動的に満たすことができます。

    loadRequired

  2. モジュールに加えられた変更を反映しています。モデルチェッカーを使用してモデルをビルドスクリプトでチェックし、モデルがモジュールファイルと一致しているかどうかを確認できます。モデルチェッカーは、スクリプト内のすべての問題を表示し、クイック修正を実行ボタンを使用して修正できるようにします。モデルチェッカーの代わりに、同じ「ファイルから必要な情報をロードする」インテンションを使用して、各モジュールを個別に修正することができます。

    modelChecker

ビルドスクリプトでのMPSモジュール宣言について覚えておくべきもう1つのことは、MPSにロードされているモジュールに依存していないということです。すべての情報はディスク上のモジュール記述子ファイルから取得されますが、モジュール自体はビルドスクリプトからは使用できない可能性があります。

MPSモジュールは、ビルドスクリプトを構成するためにmpsグループに追加することができます。MPSグループは、名前付きのモジュールの集合です。外部から参照することができます。たとえば、モジュールグループをIDEAプラグインに1つの単位として追加できます。

モジュールリソース

モジュールに必要なリソース(イメージ、アイコンなど)は、リソース コンテンツ・ルートを使って指定する必要があります。

Resources

MPSモジュールの生成とコンパイルは内部でどのように機能するのか

上記のように、モジュールに関する多くの情報がビルドスクリプトに抽出され、そこで保存されます。これにより、モジュールの依存関係が変更されたときはいつでもスクリプトを正しく更新することがユーザーに義務付けられます。ソリューションの場合、スクリプトに抽出されるのは再エクスポートされた依存関係と再エクスポートされていない依存関係の両方です。言語については、依存関係とは別に、ランタイムソリューションと拡張言語も抽出されます。

ビルドスクリプトを使ってモジュールを「ビルド」するには、2つの部分があります。このモジュールの生成とモジュールソースのコンパイルです。生成は、ソースコードをバージョン管理システムに格納し、それをモデルと同期させるプロジェクトのオプションのステップです。生成するために、ビルドスクリプト内のすべてのモジュールを生成する1つのターゲットが作成されます。モジュールは「チャンク」 - 一緒に生成できるモジュールのグループ - に分けられ、生成タスクはチャンクを一つずつ生成します。例:言語とその言語で書かれた解決策を一緒に生成することはできないため、それらは別々のチャンクに入ります。生成するチャンクのリストとは別に、generateタスクにはロードするアイデアプラグインのリストと生成に必要な他のビルドスクリプトからのモジュールのリストが提供されています。このプラグインとモジュールのリストは依存関係から計算されるため、それらの正確さは生成を成功させるために極めて重要です。これは、MPSからのモジュール生成とビルドスクリプトからのモジュール生成の大きな違いです。一方、MPSからモジュールを生成する場合、ジェネレータにはプロジェクト内のすべてのモジュールがロードされて使用可能になります。ビルドスクリプトからモジュールを生成するとき、ジェネレータはモジュールの依存関係で明示的に指定されたものだけを持ちます。そのため、ビルドスクリプトは、モジュールの依存関係の正当性を検証するためのある種の検証者として使用できます。

モジュールのコンパイルは少し違った方法で実行されます。すべてのMPSモジュールに対してjavaモジュールが生成されるため、最終的に各MPSモジュールは通常のant javacタスク(またはJavaオプションで選択された場合は同様の他のタスク)によってコンパイルされます。

そのため、生成してコンパイルするために、モジュールの依存関係が収集され、生成されたビルドxmlファイルに埋め込まれます。使用されている言語とdevkitsはモジュール記述子ファイルからビルドスクリプトを生成する間に集められます。その他の情報はビルドスクリプトノード内に格納されています。下の図では、「myproject」というプロジェクトのモジュール構造が示されています。このプロジェクトは、「mylibrary」というサードパーティのMPSライブラリーを使用しています。

normal module structure

矢印はモジュール間の依存システムを示しています。紫色の矢印はビルドスクリプトに抽出される依存関係を示し、青い矢印はどの依存関係が抽出されないかを示します。私のプロジェクトからモジュールをコンパイルして生成するために、mylibraryの中の「青い矢印」の知識が必要とされないことは容易に観察されることができます。つまり、私のライブラリーの実際のモジュールファイルは、myprojectビルドスクリプトの生成中にも存在しないかもしれません。ジェネレータが必要とするすべての情報はビルドスクリプトに含まれています。これは非常に便利です。ビルドの生成中にライブラリー全体をダウンロードしてその完全な場所を指定する必要がないため、生成プロセスではプロジェクトの依存関係からすべてのモジュール記述子をロードしないため時間とメモリを節約できます。

出典とテスト

MPSソリューションにテストモデル、すなわちステレオタイプ "@tests"のモデルが含まれている場合、それらはデフォルトではコンパイルされないフォルダー "tests_gen" に生成されます。テストをコンパイルするには、ソリューションにテストモデルがあることをビルドスクリプトで指定する必要があります。これはインスペクタで手動で行われます。解決策に利用可能な3つのオプションがあります: "with sources"(デフォルト)、"with testing"そして "with sources and tests"。

withTests

MPSの設定

mps設定により、ビルドスクリプトのMPS固有のパラメータを変更できます。"追加の側面"セクションのビルドスクリプトには、mps設定のインスタンスが複数存在することはできません。変更可能なパラメーター

  • bootstrap - このフラグを "true"に設定すると、スクリプト内のモジュール間にブートストラップ依存関係がいくつかあることを示します。通常、フラグはfalseに設定されています。詳細はブートストラップ依存関係の問題の除去を参照してください。

  • テスト生成 - trueに設定されている場合、ビルドスクリプトはモジュール生成と生成されたファイルとディスク上のファイルとの違いをテストします。ファイルはexcludeセクションでdiffから除外することができます。

  • 世代最大ヒープサイズ(MB) - 世代および世代テストのための最大ヒープサイズ。

テストモジュール生成

生成されたソースファイルをバージョン管理に保持しているプロジェクトは、ビルドスクリプトを使用して、これらの生成されたファイルが最新であることを確認できます。mps設定でテスト生成をtrueに設定すると、生成されたビルドスクリプトのテストターゲットにgentestタスクの呼び出しが表示されます。同様に、タスクを生成するために、gentestはスクリプト内のモジュール、他のビルドスクリプトからの依存関係、および必要なアイデアプラグインを読み込みます。各モジュールについて、gentestタスクは2つのテストを呼び出します: "%MODULE_NAME%.Test.Generating"および "%MODULE_NAME%.Test.Diffing"。生成中にモジュールにエラーがあるとTest.Generatingは失敗し、生成されたファイルがディスク上のファイルと異なる場合(バージョン管理からチェックアウト)、Test.Diffingは失敗します。テスト結果と統計は、TeamCityビルドサーバーでサポートされるxmlファイルにフォーマットされます。

IDEAプラグイン

アイデアプラグイン構築はMPSモジュールを含むIntelliJ IDEAまたはMPSのためのプラグインを定義します。スクリーンショットでは、そのようなプラグインの例を見ることができます。

blxx1

プラグインの宣言の最初のセクションでは、プラグインを記述した様々な情報から構成されています。その名前と説明は、フォルダー、プラグインのベンダー、など。ここで重要な文字列の名前は、キーワードのアイデアプラグインの後に行くプラグインID、です。これは他のすべての中でプラグインのユニークな識別子です。plugin.xmlファイルの作成方法には3つのオプションがあります。ビルドスクリプトのアイデアプラグインセクションに含まれる情報を単独で使用するか、提供された plugin.xmlファイルの内容で情報を充実させるか、またはカスタム plugin.xmlファイルを単独で使用することができます。

blxx2

アイデアプラグインの中の次のセクションは実際のプラグインコンテンツです - プラグインに含まれるモジュールまたはモジュールグループのセットです。

最後のセクションは他のプラグインへのプラグインの依存関係について書かれています。ルールは、"pluginB" にある "moduleB" に依存する "pluginA" にある "moduleA" がある場合、"pluginB" に対する "pluginA" の依存関係があるはずです。そのような問題を識別して報告する型システムチェックが存在します。

プラグインのレイアウトは最後に指定されています。プラグインをパッケージ化する方法は2つ考えられます。

  • 自動パッケージ化 - 提供されているすべての言語とソリューションは、プラグインのルートディレクトリーの「languages」フォルダーに配置されます。

  • 手動パッケージ - 開発者はプラグイン全体のレイアウトを手動で定義する必要があります

blxx3

MPSのターゲット

MPSプラグインは以下のターゲットを提供します。

  • generate - プロジェクト構造に含まれているmpsモジュールを生成します。

  • cleanSources - 生成されたコードをクリーンアップします(ブートストラップ依存関係のないモジュールのみ)。依存関係のブートストラップについて詳しくは、記事ブートストラップ依存関係の問題の除去を参照してください。

  • declare-mps-tasks - generatecopyModelsなどのmpsタスクを宣言するユーティリティターゲット。

  • makeDependents - このスクリプトの依存関係を一時的に閉じるためにgenerateターゲットを呼び出し(存在する場合)、次にassembleを呼び出してまとめます。各スクリプトは、その依存関係がすべて構築された後にのみ実行されることが保証されています。

モジュールテストプラグイン

jetbrains.mps.build.mps.tests言語によって提供されるモジュールテストプラグインは、MPSソリューションでNodeTestCasesおよびEditorTestCasesを実行する機能をビルドスクリプトに追加します。テストは、すべてのモジュールがコンパイルされてディストリビューション物にパッケージ化された後、つまりパッケージ化されたコードに対して実行され、コードの実際の使用を厳密に模倣した環境で呼び出されます。

テストモジュール構成

テストを含むソリューション/モジュールグループは、テストモジュール構成にグループ化されます。テストモジュール構成は、同じ環境で一緒に実行されるテストを含むソリューションのグループです。すべての必要な依存関係(たとえばモジュールとプラグイン)はその環境にロードされます。
スクリーンショットでは、実行という名前のテストモジュール構成を見ることができます。これには、ソリューションjetbrains.mps.execution.impl.testsとモジュールグループdebugger-testsが含まれています。

blxx5

テストモジュール構成にソリューションを含めるための前提条件があります。解決策は、テストを含むものとして指定する必要があります。(インスペクタで「テスト付き」または「ソースとテスト付き」を選択することによって)。モジュールグループには、テストを含むモジュールを少なくとも1つ含める必要があります。

テスト結果と統計は、xmlファイル(TeamCityでサポートされています)にフォーマットされています。

テストモジュールの実行設定構築は、MPS antテスト実行中にロードされるべきである追加のアイデアプラグインを指定する可能性をサポートします。MPS antテストの実行に必要なプラグインは、自動的に計算できないことがあります。テストが利用可能な特定のプラグインを必要とし、その情報がMPSビルド言語エンジンによってテストを含むモジュールから推論できないというシナリオがあります。そのような場合、必要なプラグインは手動で指定できます。

blxx4

MPSランナープラグイン

jetbrains.mps.build.mps.runnerによって提供されるMPSランナープラグインは、新しいビルドスクリプトエントリを有効にします - ソリューションからコードを実行します。Javaコードを保持するソリューションを指すことで、ビルドスクリプトはビルドプロセスの一部としてそれを実行することができます。

Runner

プロジェクトの「サンドボックス」ソリューションにあるJavaクラスを呼び出す最小限のビルドスクリプトは、次のようになります。

Runner1

ソリューション命令からコードを実行すると、コードを実行するMPSインスタンスで選択したプラグインを有効にできます。対応するプラグインは、その依存関係とともに有効になります。

RunnerWithPlugins

リポジトリを管理する

MPS antタスクはいくつかの新しいタグ - モジュールモジュールallmpsmodules - を使ってリポジトリの内容を完全に制御することができます。

Migrate

使い方

以下の記事では、言語プラグインを構築する方法について説明します。

MPSを使ったビルドの話題に関する記事:

最終更新日: 2019年8月30日

関連ページ:

ブートストラップ依存関係の問題の除去

定義::いつでもそれ自体を使用する言語または、言語を使用し、その言語が機能するために同じソリューションを必要とする(つまり、間接的または直接依存する)ソリューション、ブートストラップ依存関係の問題があります。なぜこれが問題なのですか:ビルドスクリプトを使用してプロジェクト全体をゼロから再構築すること...

IntelliJ IDEA言語プラグインの構築

それで、一連の言語を作成しました、IntelliJ IDEAの中のJava開発者に利用可能にしたいです。この文書では、おそらくそれらが依存するランタイムと共に、一連の言語を有効なIntelliJ IDEAプラグインにパッケージする方法を見ていきます。ビデオが好きですか?それならIntelliJ ID...

MPS言語プラグインの構築

MPSのプラグインとして言語を配布することは、IntelliJ IDEAのパッケージ言語と非常によく似ています。2つの重要な違いがありますが、IntelliJ IDEA言語プラグインの構築と同じ手順に従ってください。添付のスクリーンショットでわかるように、ビルドスクリプトはmpsに依存するはずです。...

言語のためのスタンドアロンIDEを構築する

:導入:スタンドアロンIDEという用語は、特定のビジネス目的に必要な成果物のみを含む、IDEの簡略版を指します。スタンドアロンIDEはエンドユーザーにDSLを配布する便利な方法を提供します。エンドユーザーは、IDE設計者が用意したIDEサポート、リファクタリング、およびコード分析を含む言語を、専用の...

パターン

パターン言語:パターン言語には、モデル構造のパターンを定義するという単一の目的があります。これらのパターンは、マッチングしたいノードの視覚的表現を形成します。ノードのプロパティー値がパターンで指定された値と等しい場合、パターンはノードと一致し、ノードの参照はパターンのものと同じターゲットを指し、対応...

MPS と ant の使い方

MPSとantを使った作業:編集コードはもちろんMPSエディターを必要とします。しかしモデルの生成と自動テストと統合するためにコマンドラインからテストを実行することができます。構築します。基礎としてAntが使用されます。このセクションではMPSの使い方を説明しますantを介してコマンドラインから。す...