Maven の pom を yaml 記法で記述する

# Maven の pom を yaml 記法で記述する

## 目的

[Maven](https://maven.apache.org/) のビルド構成ファイル POM で XML ではない別の記述方式を試してみます。  

## 実現すること

pom.xml を Maven の拡張機能を使用して pom.yml として yaml 記法で記述します。

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  
+ [WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  

<details>

WSL (Microsoft Store アプリ版)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

Java JDK [※ 最小構成 Java JDK の導入と Hello World!](https://qiita.com/hiroxpepe/items/8650664e466906a57996)

```sh
$ java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
```

Maven [※ 最小構成 Maven の導入と Hello World!](https://qiita.com/hiroxpepe/items/40f7f199b9be7f9e3b5b)

```sh
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.17, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
```

</details>

※ この記事では基本的に Ubuntu のターミナルで操作を行います。

## 確認用のプロジェクト作成

### プロジェクトフォルダの作成

```sh
$ cd ~
$ mkdir -p tmp/maven-yaml
$ cd ~/tmp/maven-yaml
```

※ ~/tmp/maven-yaml をプロジェクトフォルダとします。  

### アプリケーションクラスの作成

※ 確認用としてシンプルな Spring Boot アプリを記述しています。  
※ 構成を単純にする為に全ての要素を記述しています。  

```sh
$ mkdir -p src/main/java/com/example/springboot
$ vim src/main/java/com/example/springboot/SpringbootApplication.java
```

ファイルの内容

```java:SpringbootApplication.java
package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class SpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }
}
```

### pom.xml の作成

```sh
$ vim pom.xml
```

ファイルの内容

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>hello-spring-boot</artifactId>
    <version>1.0</version>
    <name>hello-spring-boot</name>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
```

### アプリのビルド

```sh
$ mvn clean install
```

Spring Boot アプリがビルド出来ました。

## 拡張機能の導入

### extensions.xml を作成

ファイル作成

```sh
$ mkdir -p .mvn
$ vim .mvn/extensions.xml
```

ファイルの内容

```sh:extensions.xml
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
    <extension>
        <groupId>io.takari.polyglot</groupId>
        <artifactId>polyglot-yaml</artifactId>
        <version>0.4.6</version>
    </extension>
</extensions>
```

### pom.xml を変換

コマンド実行

```sh
$ mvn io.takari.polyglot:polyglot-translate-plugin:translate \
    -Dinput=pom.xml \
    -Doutput=pom.yml
```

確認

```sh
$ cat pom.yml
```

ファイルの内容  
※ 出力されたまま  

```yml:pom.yml
modelEncoding: UTF-8
modelVersion: 4.0.0
parent: {artifactId: spring-boot-starter-parent, groupId: org.springframework.boot,
  relativePath: '', version: 2.7.8}
groupId: com.example
artifactId: hello-spring-boot
version: 1.0
packaging: jar
name: hello-spring-boot
properties: {java.version: 11, project.build.sourceEncoding: UTF-8}
dependencies:
- {groupId: org.springframework.boot, artifactId: spring-boot-starter-web}
- {groupId: org.springframework.boot, artifactId: spring-boot-starter-test, scope: test}
build:
  finalName: app_yml
  plugins:
  - {groupId: org.springframework.boot, artifactId: spring-boot-maven-plugin}
childProjectUrlInheritAppendPath: true
```

### pom.yml でのビルド

pom.yml の内容を変更

```sh
$ vim pom.yml
```

ビルド

```sh
$ mvn clean install -f pom.yml
```

※ pom.yml を編集した内容でビルド出来ました。

### pom.yml を pom.xml に再変換

コマンド実行

```sh
$ mvn io.takari.polyglot:polyglot-translate-plugin:translate \
    -Dinput=pom.yml \
    -Doutput=pom.xml
```

確認  
※ 出力されたまま  

```sh
$ cat pom.xml
```

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" child.project.url.inherit.append.path="true" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.8</version>
    <relativePath></relativePath>
  </parent>
  <groupId>com.example</groupId>
  <artifactId>hello-spring-boot</artifactId>
  <version>1.0</version>
  <name>hello-spring-boot</name>
  <properties>
    <java.version>11</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>app2</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
```

※ 編集した内容が pom.xml に反映されました。

## まとめ

+ pom.xml を Maven の拡張機能を使用して pom.yml として yaml 記法で記述することが出来ました。
+ xml 形式が yaml 形式に変換され、文字的な記述量が減ったと思います。
    + しかし個人的に pom.xml の形式に慣れ過ぎているので読みやすいか？と言われれば微妙だと感じました。
+ 実際には VS Code などでフォーマッタを使用するので読みやすさについては改善すると思います。
    + しばらく試し運用して様子を見ようと思いました。

## 公式

+ [polyglot-maven](https://github.com/takari/polyglot-maven)