VS Code - z/OS連携[Zowe Explorer V3編] (3)VS Codeからのユーザー・ビルド

# はじめに

メインフレーム・アプリケーション開発支援の機能を提供するDBB(Dependency Based Build)という有償製品があります。これはz/OS上にインストールして利用するもので、アプリケーションのビルド(コンパイル/リンク)に関連する操作をGroovyから行えるAPIをDBB Toolkitとして提供しています。これを利用すると、Groovyスクリプトでビルド操作を行うことができます。さらに、このDBB Toolkitを利用したビルド用のフレームワーク "zAppBuild" がOSSとして提供されています。
VS CodeのZ Open Editor Extensionでは、zAppBuild+DBBと連携するための機能が提供されており、VS Codeからスマートにビルド処理を行うことができるようになっています。

当記事では、VS CodeからzAppBuild/DBB利用する流れをシンプルなケースで見ていきたいと思います。

※注意
当記事で記載する内容は、DBB V2.0をベースとしています。DBB V3.0ではzAppBuildに相当する機能を製品に取り込んでzBuilderという別の機能を提供しています(DBB V3.0でもzAppBuildは継続利用できます)。DBB V3.0のzBuilderについてはここでは触れません。

参考:
[DBB V3.0 - What is new and noteworthy in IBM Dependency Based Build](https://www.ibm.com/docs/en/dbb/3.0?topic=overview-what-is-new-noteworthy)
>NOTE: The zBuilder is provided as an alternative to the IBM Open Source zAppBuild build framework, not necessarily as a replacement. The zBuilder uses the same underlying DBB toolkit APIs as zAppBuild. There are no plans to remove these APIs or to stop maintaining zAppBuild for the foreseeable future.

## 関連記事

[VS Code - z/OS連携[Zowe Explorer V3編] (1)概要, 基本構成](https://qiita.com/tomotagwork/items/4eb3e51b01b8db76cefc)
[VS Code - z/OS連携[Zowe Explorer V3編] (2)基本操作](https://qiita.com/tomotagwork/items/7e6ab9970d4b8a1fb219)
[VS Code - z/OS連携[Zowe Explorer V3編] (3)VS Codeからのユーザー・ビルド](https://qiita.com/tomotagwork/items/45e46ca55e38cec44a58)

# 全体像
ここではUTフェーズにおける、VS Codeで編集したソースを開発環境(z/OS上)でコンパイルする、いわゆるユーザー・ビルドと呼ばれる操作に着目します。Gitで管理されたソースを編集、ビルドする、というシナリオで使われることが想定される機能ですので、以下のようにGit管理のソースを編集するという例で考えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/cca140c0-c2f1-7327-af3e-54d493c40c50.png)

ユーザー・ビルドの基本的な操作の流れは以下の通りです。

(1) Git Serverから編集対象のソースが含まれるリポジトリをPCにクローンします
(2) VS Codeのエディターでソースを編集します
(3) 編集したソースをビルドします
(4) 必要に応じてUnit Testを実施します
(5) ソースの変更に問題がなければGit Serverに変更内容を反映します

(3)の操作では、VS Codeで編集したソースを右クリックし、IBM User Build実行のメニューを選択すると、以下の一連の操作が自動で行われます。
 - 当該ソース、および、関連するCOPYBOOKを開発環境(z/OS)に転送
 - z/OS上でコンパイル実行(ssh経由でコンパイル用のGroovy Scriptを実行)
 - コンパイル結果をPC上にダウンロード

Unit Testは対象のソースの形態や、アクセスするリソース等によって実施方法や実施可否が変わるので、やり方は適宜検討する必要があります。



※zAppBuildを利用したユーザー・ビルドについての情報は、様々なドキュメントに分散していてちょっと分かりにくいです。IDz EE(IBM Developer for Z Enterprise Edition)にはDBBも含まれており、VS Codeからの利用についての情報も記載がありますのでそちらが比較的分かりやすいと思います。以下に主要な参考情報のリンクをまとめておきます。
参考: 
[GitHub - zAppBuild](https://github.com/IBM/dbb-zappbuild)
[IDz V1.7 - Setting up the user build](https://www.ibm.com/docs/en/developer-for-zos/17.0?topic=code-setting-up-user-build)
[IDz V1.7 - Configuring your applications with ZAPP files](https://www.ibm.com/docs/en/developer-for-zos/17.0?topic=editing-configuring-your-applications-zapp-files)
[GitHub - zopeneditor-sample/zapp.yaml](https://github.com/IBM/zopeneditor-sample/blob/wazi-main/zapp.yaml)


# VS Codeからのユーザー・ビルド実行

## 環境構築

VS Codeからユーザー・ビルドを実行するために必要な設定について見ていきます。

### z/OS側

DBB製品導入と基本的なセットアップを導入ガイドに従って実施しておく必要があります(詳細は割愛)。
参考:
[DBB V2.0 - Installing and configuring DBB](https://www.ibm.com/docs/en/dbb/2.0?topic=installing-configuring-dbb)

zAppBuildをGitHubから入手し、USS上の適当なディレクトリに展開しておく必要があります(詳細は割愛)。
参考:
[DBB/zAppBuildについてのメモ - (1)概要](https://qiita.com/tomotagwork/items/d3b08b10137a0d87416d)

### PC側

VS Codeを導入し、VS Code上に、Zowe Explorer Extension、IBM Z Open Editor Extensionを導入します(詳細は割愛)。
参考:
[VS Code - z/OS連携[Zowe Explorer V3編] (1)概要, 基本構成](https://qiita.com/tomotagwork/items/4eb3e51b01b8db76cefc)


## 設定

ユーザー・ビルドに関連する設定箇所は分散していて分かりにくいため全体像を整理します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/09560514-a397-4d7f-b866-2f4ffcd74909.png)
上の図の赤字部分の設定を行っていきます。

※一旦ここではユーザー・ビルド(CD/UTフェーズにおける、編集した特定のソースをビルドする操作)に着目していますが、zAppBuildは汎用的な仕組みを提供するフレームワークですので、後続のフェーズで使用可能なプロパティなども含んでいます(例えばFull Buildと呼ばれる、Project内のソースを全て一括でビルドする場合に有効なプロパティなど)。

### 1. zAppBuild関連設定

#### 1-(1) 開発環境依存情報(build-conf)

build-conf関連のプロパティーでは、開発環境として使用するz/OS環境に依存する情報を設定していきます。ビルド環境のUSS上にクローンしたzAppBuildのdbb-zappbuild/build-conf/以下にあるプロパティ・ファイルをカスタマイズすることになります。
最低限カスタマイズが必要なプロパティとしては、datasets.properties、Cobol.propertiesファイルあたりです。それ以外のファイル/プロパティは必要に応じて変更するということになるでしょう。主なものを以下にいくつか補足します。

##### datasets.properties
参考: [datasets.properties](https://github.com/IBM/dbb-zappbuild/blob/main/build-conf/datasets.properties)

このファイルでは、z/OS、LE、コンパイラ関連のライブラリーや、ミドルウェア関連のライブラリーのHLQを指定することになります。ファイル中のコメントの記述を参考に実環境と照らし合わせて設定します。利用しないミドルウェアについてのプロパティーはブランクのままで構いません。

##### Cobol.properties
参考: [Cobol.properties](https://github.com/IBM/dbb-zappbuild/blob/main/build-conf/Cobol.properties)

基本的にはサンプル構成でよいと思いますが、ポイントとなるプロパティーは確認しておくとよいでしょう。

【cobol_compiler】
コンパイラとして使用するプログラムを指定します。
例: `cobol_compiler=IGYCRCTL`

【cobol_linkEditor】
リンカーとして使用するプログラムを指定します。
例: `cobol_linkEditor=IEWBLINK`

【cobol_xxxPDS】
ビルド時に各種リソースを配置するPDSのデータセット名を指定します。

```properties:Cobol.properties例
# COBOL source data sets
cobol_srcPDS=${hlq}.COBOL
cobol_cpyPDS=${hlq}.COPY
cobol_objPDS=${hlq}.OBJ
cobol_dbrmPDS=${hlq}.DBRM
cobol_BMS_PDS=${team}.BMS.COPY

# COBOL load data sets
cobol_loadPDS=${hlq}.LOAD
```

上の例ではCOBOLのソースは`${hlq}.COBOL`、COPYBOOKは`${hlq}.COPY`、生成されるロードモジュールは`${hlq}.LOAD`という具合です。`${hlq}`はビルド実行に動的に設定される変数です。

【cobol_srcDatasets, cobol_srcOptions, cobol_loadDatasets, cobol_loadOptions】
対象のデータセットが存在しない場合動的に作成されますが、その際データセット作成時のオプションを指定します。

```properties:Cobol.properties例
# List the data sets that need to be created and their creation options
cobol_srcDatasets=${cobol_srcPDS},${cobol_cpyPDS},${cobol_objPDS},${cobol_dbrmPDS}
cobol_srcOptions=cyl space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library)
cobol_loadDatasets=${cobol_loadPDS}
cobol_loadOptions=cyl space(1,1) dsorg(PO) recfm(U) blksize(32760) dsntype(library)
```

#### 1-(2) アプリケーション依存情報(application-conf)

アプリケーションに依存するプロパティーは、ビルド対象のアプリケーションのソースと一緒にGitで管理される想定で、`application-conf/`以下に配置します。

まず、application.properties、file.properties辺りは必須です。また、ここではCOBOLバッチのビルドを想定し、Cobol.propertiesをカスタマイズしていきます(他の言語やミドルウェアを使用する場合はそれに応じて追加でプロパティーを設定していくことになります)。

ここでは最低限考慮すべきプロパティについて見ていきます。

##### application.properties
参考: [application.properties](https://github.com/IBM/dbb-zappbuild/blob/main/samples/application-conf/application.properties)

【applicationPropFiles】
他に読み込むべきプロパティファイルをカンマ区切りで指定します。file.propertiesは必須と思ってよいでしょう。加えて、ビルド対象にCOBOL, PL/Iが含まれていればそれら言語ごとのプロパティファイルを指定するといった具合です。
例: `applicationPropFiles=file.properties,Cobol.properties,PLI.properties,...`

【buildOrder】
複数のソースのビルドを行う際に、その種類ごとにどの順番でビルドを行うかを制御します。ここでは呼び出すビルド用のGroovyスクリプトの順番を指定します。
例えば、CICSのアプリケーションを想定し、BMSマップとそれを使用するCOBOLソースが含まれていたとすると、先にBMSマップをビルドしてCOPYBOOKを生成し、そのCOPYBOOkを使用してCOBOLソースをビルドする必要があります。つまり、ビルド用スクリプトとしては、BMS.groovy => Cobol.groovy の順番で実行して欲しいということになります。
例: `buildOrder=BMS.groovy,Cobol.groovy,...`

単純に独立したCOBOLバッチとPL/Iバッチがそれぞれ含まれているようなケースでは特に順序性は意識する必要はありませんので、使用するスクリプトを任意の順番で指定すればよいです。
例: `buildOrder=Cobol.groovy,PLI.groovy,...`

【copybookSearch】
転送先のUSS上でビルド対象のCOBOLソースから参照されるCOPYBOOKの探索パスを指定します。基本的にはZAPPファイル(zapp.yaml)中でPropertyGroupに指定したlocalのsyslib指定と整合性を合わせることになります。
例: `copybookSearch = search:${workspace}/?path=${application}/copybook/*.cpy;${application}/COPYLIB/*.cpy;${application}/COPYLIB-MVS/*.cpy`
この探索パスから見つかったファイルがMVSデータセットにコピーされてコンパイル時に参照されます。

【pliincludeSearch】
転送先のUSS上でビルド対象のPL/Iソースから参照されるINCLUDEファイルの探索パスを指定します。基本的にはZAPPファイル(zapp.yaml)中でPropertyGroupに指定したlocalのsyslib指定と整合性を合わせることになります。
例: `pliincludeSearch = search:${workspace}/?path=${application}/INCLUDES/*.inc;${application}/INCLUDELIB/*.inc;${application}/INCLUDELIB-MVS/*.inc`
この探索パスから見つかったファイルがMVSデータセットにコピーされてコンパイル時に参照されます。

##### file.properties
参考: [file.properties](https://github.com/IBM/dbb-zappbuild/blob/main/samples/application-conf/file.properties)

【dbb.scriptMapping】
ビルドに使用する言語別スクリプトと、ソースのマッピングを行います。例えば、.cblという拡張子のついたファイルはCOBOLソースであると判断し、Cobol.groovyというビルド用スクリプトを使用してビルドする、ということをマッピング情報として与えておきます。
例: `dbb.scriptMapping = Cobol.groovy :: **/*.cbl`
このマッピング情報から、ソースのパスからビルド用スクリプトが判定されてビルドされることになります。
このマッピング情報は複数指定することができます。

```properties:file.properties
dbb.scriptMapping = Cobol.groovy :: **/*.cbl
dbb.scriptMapping = PLI.groovy :: **/*.pli
dbb.scriptMapping = Assembler.groovy :: **/*.asm
...
```

##### Cobol.properties
参考: [Cobol.properties](https://github.com/IBM/dbb-zappbuild/blob/main/samples/application-conf/Cobol.properties)

【cobol_compilerVersion】
COBOL Compilerのバージョンを指定します。
例: `cobol_compilerVersion=V6`
この値は、`build-conf/datasets.properties`で指定される`SIGYCOMP_xx`プロパティの`xx`部分に相当します。

【cobol_compileParms】
COBOLコンパイラ・オプションを指定します。
例: `cobol_compileParms=LIB`

【cobol_linkEditParmss】
リンク・オプションを指定します。
例: `cobol_linkEditParms=MAP,RENT,COMPAT(PM5)`

### 2. ユーザー・ビルド情報設定

#### 2-(1) 共通(zapp.yaml)
参考: [zapp.yaml](https://github.com/IBM/zopeneditor-sample/blob/wazi-main/zapp.yaml)

ZAPPファイル(zapp.yaml)にてユーザー・ビルドの実行方法を指定します。
以下のように`type: dbb`を指定したプロファイルで指定することになります。

```yaml:zapp.yaml例
profiles:
  - name: dbb-userbuild
    type: dbb
    settings:
      application: Appl01
      command: "$DBB_HOME/bin/groovyz -DBB_PERSONAL_DAEMON"
      buildScriptPath: "/global/dbb/dbb-zappbuild/build.groovy"
      buildScriptArgs:
        - "--userBuild"
        - "--workspace ${zopeneditor.userbuild.userSettings.dbbWorkspace}"
        - "--application ${application}"
        - "--hlq ${zopeneditor.userbuild.userSettings.dbbHlq}"
        - "--outDir ${zopeneditor.userbuild.userSettings.dbbLogDir}"
        - "--dependencyFile ${dependencyFile}"
      additionalDependencies:
        - application-conf
      logFilePatterns:
        - "${buildFile.basename}.log"
        - "BuildReport.*"
```

プロパティ補足

- **name**: プロファイル名 (後述のsetting.jsonのdbbDefaultZappProfileと合わせる)
- **type**: `dbb`で固定
- **settings.application**: アプリケーション識別子(USSに転送する際のトップのディレクトリ名として使用される)
- **settings.command**: DBB提供のgroovyスクリプト起動コマンド
- **settings.buildScriptPath**: zAppBuild提供のbuild.groovyのパス
- **settings.buildScriptArgs**: zAppBuildのbuild.groovyに渡す引数
- **additionalDependencies**: zAppBuildのアプリケーション関連プロパティファイル保管ディレクトリ
- **logFilePatterns**: ダウンロード対象のログファイル名


#### 2-(2) ユーザー個別(setting.json)

まず、開発環境として使用するz/OSへの接続プロファイルを指定する必要があります。z/OSMF(or RSE)、および、SSHのプロファイルを指定する必要があります。
設定画面だとZopeneditor: Zoweの欄で以下のように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/11c4e2a7-6da7-1f4b-1d41-0e05c0500fd6.png)

settings.jsonファイルだと以下のようになります。

```json:settings.json例
...
"zopeneditor.zowe": {
    "defaultCliProfile": "lpar1.zosmf",
    "defaultSshCliProfile": "lpar1.ssh"
},
...
```

次に、ユーザー・ビルド時に使用されるユーザー固有情報を変数として指定します。
設定画面だとZopeneditor > Userbuild: User Settingsの欄で以下のように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ffa562f7-6871-261e-1c1c-1a4429152d0f.png)


settings.jsonファイルだと以下のようになります。

```json:settings.json例
...
"zopeneditor.userbuild.userSettings": {
    "dbbWorkspace": "/u/user01/projects",
    "dbbHlq": "USER01.DBB",
    "dbbLogDir": "/u/user01/projects/logs",
    "dbbDefaultZappProfile": "dbb-userbuild"
}
...
```

ここで指定している変数について補足します。

- **dbbWorkspace**: ソースや関連プロパティ・ファイルは、一旦z/OS上のUSSファイルシステム上に転送されますが、その一時ファイルを保持しておくための作業ディレクトリのトップを指定します。このディレクトリは事前に作成しておく必要があります。
- **dbbHlq**: ソースやCOPYBOOKなどビルドに必要なリソース、ロードモジュールなどの生成物が配置されるデータセットのHLQです。存在しなければプロパティの指定に基づいて動的に作成されます。
- **dbbLogDir**: ビルド結果のログを保持するUSSファイルシステム上のディレクトリです。
- **dbbDefaultZappProfile**: ZAPPファイル(zapp.yaml)で指定されるユーザー・ビルド用のプロファイル名


## ユーザー・ビルド実行例

実際に、シンプルなサンプル・ソースを使ってユーザー・ビルドを実行した時のログを元に流れを解説していきます。

使用するGitリポジトリ:　https://github.com/tomotagwork/ZoweTest2025
ユーザー・ビルドするCOBOLソース: [TSUB02.cbl](https://github.com/tomotagwork/ZoweTest2025/blob/main/Test01/cobol/TSUB02.cbl)
ユーザー・ビルド実行時のログ: [User Build Log](https://github.com/tomotagwork/ZoweTest2025/blob/main/logs_cobol_TSUB02/userbuild_withFullUpload_verbose.txt)

### ユーザー・ビルドのフロー
ビルド対象のソースをエディターで開き、右クリック - 「フルアップロードでIBM User Buildを実行します」を選択すると、ユーザー・ビルドが走ります。
この時、裏で以下のような処理が自動的に実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/362a7064-bbb5-52a9-5bd2-d2fa8c436ea5.png)

個々の処理について補足していきます。

#### (1) 各種プロパティーのチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/921c7427-9c03-001c-415e-0ccc0c9835dd.png)

VS Codeのワークスペースのルートや、settings.json, ZAPPファイル(zapp.yaml)のプロパティーを確認します。
settings.json に指定されている SSH接続用プロファイル(defaultSshCliProfile) の指定に基づき、このプロファイルでSSH接続できるかどうかチェックします。

.gtiattributesファイルがあるかどうかもチェックし、あれば、以降のファイル転送の際には.gitattributesファイルに指定された情報を元にコード変換が行われます。

参考:
[Character conversion using .gitattributes](https://ibm.github.io/zopeneditor-about/Docs/ebcdic_encoding.html#character-conversion-using-gitattributes)
[dbb-zappbuild/.gitattributes](https://github.com/IBM/dbb-zappbuild/blob/main/.gitattributes)

#### (2) アプリ依存情報のアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/411e3c26-b2d4-00ad-97c0-6db5debe27da.png)

`application-conf`ディレクトリ(zapp.yamlの`additionalDependencies`で指定されたディレクトリ)以下のファイルをUSS上にアップロードします。
アップロードされる先は、ディレクトリ`<dbbworkspece>\<application>`です。`<dbbworkspace>`はsettings.json, `<application>`はzapp.yamlで指定される値です。
今回の例では、`/u/user01/projects/Appl01/`ということになります。

※補足:
VS Code上でビルド対象のソースを右クリックすると、ユーザー・ビルド用のメニューとしては以下の2つが選択できます。
- 「IBM User Buildを実行します」
- 「フルアップロードでIBM User Buildを実行します」

両者の違いは、この`application-conf`以下のプロパティ・ファイルをアップロードするかどうかの違いです。最初の一回、もしくは、application-conf以下のファイルを書き換えた場合は"フルアップロード"する必要があります。

#### (3) ソースのアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/868cd9d4-997f-c95b-20f7-31b661d1d95f.png)

ビルド対象のソースをUSS上にアップロードします。アップロードされる先は、application-confと同様、ディレクトリ`<dbbworkspece>\<application>`です。
今回は`Test01/cobol/TSUB02.cbl`がビルド対象のソースなので、`/u/user01/projects/Appl01/Test01/cobol/TSUB02.cbl`にアップロードされます。

#### (4) ソースから参照しているCOPYBOOKをアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/e46876e8-7a3e-470b-6b37-2bf21011d583.png)

ビルド対象のソースから参照しているCOPYBOOKを探索します(探索パスはzapp.yamlのProperty Group)。
今回は、以下の2つのCOPYBOOKを参照しているので、これらをUSS上にアップロードします。
- `Test01\copybook\CPPARM02.cpy` ⇒ `/u/user01/projects/Appl01/Test01/copybook/CPPARM02.cpy`
- `Test01\copydir\copybook2\CPPARM22.cpy` ⇒ `/u/user01/projects/Appl01/Test01/copydir/copybook2/CPPARM22.cpy`

さらに、このソースとの依存関係の情報を`.userbuilddependencies`というファイルに書き出し、USS上にアップロードします。配置先は、settings.jsonの`dbbLogDir`で指定したディレクトリです。今回の場合は、
`/u/user01/projects/logs/.userbuilddependencies`ファイルが作成されます。

中身は以下の通りです。

```xxx:.userbuilddependenciesファイル例
{"fileName":"/u/user01/projects/Appl01/Test01/cobol/TSUB02.cbl","isCICS":false,"isSQL":false,"isDLI":false,"isMQ":false,"dependencies":["/u/user01/projects/Appl01/Test01/copybook/CPPARM02.cpy","/u/user01/projects/Appl01/Test01/copydir/copybook2/CPPARM22.cpy"],"schemaVersion":1}
```

#### (5) ビルド・スクリプト実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/1d2d6668-bf9a-7ced-9293-9cd085daaa13.png)

zapp.yamlファイルに指定したdbbプロファイルに従い、DBB/zAppBuildのビルド用スクリプトが実行されます。

```yaml:zapp.yaml抜粋
...
      command: "$DBB_HOME/bin/groovyz -DBB_PERSONAL_DAEMON"
      buildScriptPath: "/global/dbb/dbb-zappbuild/build.groovy"
      buildScriptArgs:
        - "--userBuild"
        - "--workspace ${zopeneditor.userbuild.userSettings.dbbWorkspace}"
        - "--application ${application}"
        - "--hlq ${zopeneditor.userbuild.userSettings.dbbHlq}"
        - "--outDir ${zopeneditor.userbuild.userSettings.dbbLogDir}"
        - "--dependencyFile ${dependencyFile}"
...
```

上のプロパティ内で`${xxx}`で指定されている部分は変数なのでこの部分が適宜解釈されて、結果的には以下のようなコマンドがSSH経由で実行されることになります。

`$DBB_HOME/bin/groovyz -DBB_PERSONAL_DAEMON /global/dbb/dbb-zappbuild/build.groovy --userBuild --workspace /u/user01/projects --application Appl01 --hlq USER01.DBB --outDir /u/user01/projects/logs --dependencyFile /u/user01/projects/logs/.userbuilddependencies '/u/user01/projects/Appl01/Test01/cobol/TSUB02.cbl'`

※$DBB_HOMEについては、USS上の環境変数としてDBBインストールのパスを指定しておく必要があります。このコマンドは、settings.jsonの`defaultSshCliProfile`で指定したSSH用プロファイルに基づいてSSH接続されますので、ここで使用されるユーザーでSSH接続されたシェルにて環境変数が有効化されている必要があります。(例えば全体に有効化するのであれば`/etc/profile`に指定。)

ここでは、実行されるスクリプトの動作について少し深掘りしていきます。

##### (5)-1 build.groovy

###### initializeBuildProcess()

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L36

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L104

メソッドinitializeBuildProcessにて必要な変数設定などを行います。主な処理は以下の通りです。

- スクリプト実行時の引数の解析
- プロパティ設定(build-confのプロパティ・ファイル、application-confのプロパティ・ファイルをそれぞれ読み込み、スクリプトの引数と合わせて各種プロパティ情報を設定する)

###### createBuildList()

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L48

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L569

ここでは、指定したビルド・オプションに応じて、ビルド対象となるプログラムのリストを作成します。
オプション等によってビルド対象のプログラムが変わってきます。例えば、User Buildの場合特定のプログラムをビルドすることになるので、引数で指定したプログラムがビルド対象になりますし、Full Buildの場合は含まれる全てのソースがビルド対象になります(application.propertiesのexcludeFileListに指定されたファイルは除外される)。
今回のケースでは、`/u/user01/projects/logs/buildList.txt`というビルドリストファイルが作成され、中身としては、`Appl01/Test01/cobol/TSUB02.cbl`ファイル(ユーザービルド対象のソース)が1つだけ追記されます。

```txt:/u/user01/projects/logs/buildList.txt
Appl01/Test01/cobol/TSUB02.cbl
```

###### ビルド用スクリプト実行
https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L65

`application-conf\application.properties`で指定したbuildOrderの順番に、ビルド用のスクリプトを実行していきます。今回は、`buildOrder=Cobol.groovy,PLI.groovy`が設定されているので、COBOLソースのビルド、PL/Iソースのビルドの順番で実行されます。
まず、COBOLソースのビルドが行われるので、buildList.txtに記載されているファイルのうち、Cobol.groobyでビルドされるべきソース(つまりCOBOLのソース)を抽出して、それを引数にCobol.groovyを実行します。
この判断は、`application-conf\file.properties`で指定したdbb.scriptMappingの指定に基づき、[ScriptMappings.getMappedList()](https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L68)というDBB提供のメソッドにより判断されます。

```properties:file.properties
...
# Script mappings for all application programs
dbb.scriptMapping = Assembler.groovy :: **/*.asm,*.asm
dbb.scriptMapping = BMS.groovy :: **/*.bms,*.bms
dbb.scriptMapping = Cobol.groovy :: **/*.cbl,*.cbl
dbb.scriptMapping = LinkEdit.groovy :: **/*.lnk,*.lnk
dbb.scriptMapping = PLI.groovy :: **/*.pli,*.pli
...
```

今回のケースではTSUB2.cblファイル1つのみがビルド対象なので、このファイルが引数に渡されてCobol.groovyが実行されます。

※COBOLのビルドが終わったら PLI.groovyが実行される流れとなりますが、今回はビルド対象のプログラムはTSUB2.cblだけなので、PLI.groovyは実行されません。

(5)-2へ続く...


##### (5)-2 Cobol.groovy

build.broovyによりビルド対象のソースと、それに対応する言語のスクリプトが判定され、Cobol.groovyが呼び出されます。引数でビルド対象のCOBOLソースのリストが渡されます。
今回はTSUB2.cblファイルのみがビルド対象です。

###### MVSデータセットの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/343738f2-dc16-7501-f057-78cab446e582.png)

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L24

ビルド対象のソース、COPYBOO、オブジェクトモジュール、ロードモジュールなど、ビルド(コンパイル/リンク)の処理の過程で必要なデータセット(PDS)を作成します。これは、z/OS上の`build-conf/Cobol.properties`に指定された定義に基づき作成されます。

```properties:Cobol.properties例
# COBOL source data sets
cobol_srcPDS=${hlq}.COBOL
cobol_cpyPDS=${hlq}.COPY
cobol_objPDS=${hlq}.OBJ
cobol_dbrmPDS=${hlq}.DBRM
cobol_BMS_PDS=${team}.BMS.COPY

# COBOL load data sets
cobol_loadPDS=${hlq}.LOAD

...

# List the data sets that need to be created and their creation options
cobol_srcDatasets=${cobol_srcPDS},${cobol_cpyPDS},${cobol_objPDS},${cobol_dbrmPDS}
cobol_srcOptions=cyl space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library)
cobol_loadDatasets=${cobol_loadPDS}
cobol_loadOptions=cyl space(1,1) dsorg(PO) recfm(U) blksize(32760) dsntype(library)
...
```

今回のケースでは、settings.jsonで`"dbbHlq": "USER01.DBB"` を指定しているので、以下のデータセットが作成されることになります。

- USER01.DBB.COBOL
- USER01.DBB.COPY 
- USER01.DBB.DBRM 
- USER01.DBB.LOAD 
- USER01.DBB.OBJ  

※既にデータセットがあればそれがそのまま使われます。

###### ビルド対象リストのソート

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L27

ファイルのランクに基づいてビルドの順番をソートします。ビルド対象のソースが複数あって順番を制御したい場合は、`application-conf\file.properties`のcobol_fileBuildRankプロパティーでファイルにランク付けをすることができます。
今回ビルドするソースは1つだけなのでここは実質意味がありません。

###### ビルド処理

ここからがビルド対象ファイルごとに行われる一連のビルド処理です。

**(a) 依存関係ファイル分析用のResolver作成**

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L43-L44

`application-conf\application.properties`のcopybookSearchプロパティーの指定に基づき、依存関係ファイル分析用のResolverが作成されます。

**(b) 必要なファイルをUSSからMVSデータセットにコピー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/164e6065-da25-4d17-ed9f-97fcfcee64ff.png)

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L50

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/utilities/BuildUtilities.groovy#L99

ターゲットのソースと、そのソースに直接的に依存関係のあるファイル(COPYBOOKなど)をUSSからPDSにコピーします。

VS CodeによるUserBuildの場合は、VS Code側で対象ソースの依存関係をサーチしてそのリストを作成し、それを引数で渡した上でzAppBuildを呼び出します。そのため、その受け渡されたファイル(userBuildDependencyFile)から依存関係のあるファイルを判別して、PDSにコピーすることになります。
今回のケースでは(a)で作成されたResolverは使用されません。


**(c) ソースファイルの属性確認**

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L54

コンパイル対象のソースについてのLogicalFileというオブジェクトを生成し、ソースの属性を取得します。LogicalFileというのは、そのソースファイルの属性情報を以下のような構造で保持しているオブジェクトです。言語、ファイルパス、依存関係のあるファイル、などの情報を含みます。

```
{
  "lname": "TSUB02",
  "file": "Appl01/Test01/cobol/TSUB02.cbl",
  "language": "COB",
  "cics": false,
  "sql": false,
  "dli": false,
  "mq": false,
  "logicalDependencies": [
    {
      "lname": "CPPARM02",
      "library": "SYSLIB",
      "category": "COPY"
    },
    {
      "lname": "CPPARM22",
      "library": "SYSLIB",
      "category": "COPY"
    }
  ]
}
```

**(d) コンパイル・ステップの作成**

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L67

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L190

JCLで言う所の、コンパイル用のステップに相当する情報を組み立てます。
コンパイル・オプションは、`application-conf\Cobol.properties`の`cobol_compileParms`などの値が反映されます。

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L290

コンパイル・ステップの最後に、SYSPRINTの情報をUSS上のログファイル(ここではTSUB02.log)に書き出すコマンドを追加しています。

**(e) リンク・ステップの作成**

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L69

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L297

JCLで言う所の、リンク用のステップに相当する情報を組み立てます。
リンク・オプションは、`application-conf\Cobol.properties`の`cobol_linkEditParms`などの値が反映されます。また、`application-conf\file.properties`の`cobol_linkEdit`で、リンクを実施しない(コンパイルのみ実行する)プログラムを指定することも可能です。この指定によりリンク不要と判断さえたプログラムはリンクは実施せず、コンパイルのみ実行されることになります。

今回のケースでは普通にコンパイル、およびリンクのステップが実行されます。

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L403

リンク・ステップの最後に、SYSPRINTの情報をUSS上のログファイル(ここではTSUB02.log)に書き出すコマンドを追加しています(コンパイル結果にAppendされる)。

**(f) JOB実行**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/22450662-0d6b-9ebb-5cdf-5376025060a1.png)

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/languages/Cobol.groovy#L73

上で作成したコンパイル、リンクのステップをJOBとして実行します。

一通りCOBOLのビルド処理が終わったので呼び出し元のbuild.groovyに処理が戻ります。

##### (5)-3 build.groovy

###### finalizeBuildProcess()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8180d26a-63ec-6079-d38b-d58ffd018e4f.png)

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L95

https://github.com/IBM/dbb-zappbuild/blob/3.10.0/build.groovy#L95

ビルドレポートファイルを作成します。
今回は `/u/User01/projects/logs/`以下に作成されます。

#### (6) ログのダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/d492d5d7-4469-39c8-7475-62d8655c0aca.png)

`/u/User01/projects/logs/`に、ビルド結果のファイルが生成されるので、そっからzapp.yamlの`logFilePatterns`の指定に合致するパターンのファイルをローカルPCにダウンロードします。
今回の場合は、以下のファイルがダウンロードされます。

- `/u/user01/projects/logs/TSUB02.log` ⇒ `Test01\logs\TSUB02.log`
- `/u/user01/projects/logs/BuildReport.html` ⇒ `Test01\logs\BuildReport.html`
- `/u/user01/projects/logs/BuildReport.json` ⇒ `Test01\logs\BuildReport.json`

















# 補足: Advanced Capabilities の有効化

IBM Z Open Editorで提供される機能のうち、先の記事で示したような基本操作は、無償の範囲で利用できます。しかし、一部の機能は有償ライセンスが必要となります。ユーザービルドに関しては、ビルド結果のレポートを解釈し、問題(Problem)viewにエラーを表示する機能が Advanced Capablilities として提供されています。この機能を利用したい場合は、Advanced Capabilitiesを明示的に有効化する必要があります。

参考:
[Advanced Capabilities - Overview](https://ibm.github.io/zopeneditor-about/Docs/advanced_overview.html)
[Activating advanced capabilities - Manual activation](https://ibm.github.io/zopeneditor-about/Docs/advanced_activation.html#manual-activation)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8b0cbc04-5fa7-f6ad-14e9-6e00fc84ba87.png)