Study/Java

Antora 사용해 보기

Bluesky_ 2024. 6. 12. 17:29
반응형

Spring Framework 문서가 antora로 제공된 지 꽤 시간이 지났는데 Spring Boot 문서도 이번 3.3.0부터 antora로 변경되었다.
https://antora.org/

요즘 오픈 소스 사이트 문서들을 보면 antora로 빌드하는 경우가 상당히 많아 antora 사용 방법에 대해 살펴보았다.

Antora 소개

Antora는 asciidoc 기반 문서를 기반으로 site 문서 (웹 기반 문서)를 생성하는 도구이다.

https://www.algolia.com/

antora를 사용하면 여러 git repository에 위치한 adoc 문서들을 취합하고 템플릿을 사용하여 하나의 통일된 스타일의 site 문서로 구성할 수 있다.
git repository의 branch 단위의 문서를 가져와 버전별 문서 관리가 가능하다.
템플릿을 사용하여 상단 메뉴를 구성하고 repository 단위로 좌측 메뉴를 구성하기 때문에 asciidoc을 통해 생성한 html 페이지보다 좀 더 웹에서 사용하기 편한 기능을 제공하고 있다.
또한 algolia를 사용하면 문서 검색 기능도 확장할 수 있다.

Spring의 공식 문서를 보면 어떤 모양의 문서인지 확인할 수 있다.

https://docs.spring.io/spring-boot/

Antora 빌드 방식

https://docs.antora.org/antora/latest/how-antora-works/

antora는 대략 다음과 같이 순서로 site 문서를 생성한다.

  • antora가 설정된 project에서 빌드를 수행하면 (node로 실행)
  • antora가 설정된 project에 위치한 playbook 설정을 기준으로
  • git 또는 로컬 repository의 대상 adoc 문서를 가져오고
  • 사용하려는 템플릿을 가져와서
  • 각 repository에 설정된 antora.yml 을 참고하여 site 문서로 생성

정리하면

  • 여러 repository의 adoc 문서를 취합하여 site 문서를 생성할 antora project
  • 문서가 작성되어 있는 여러 git repository
    이렇게 있으면 antora site 문서를 만들게 된다.

설정

antora 빌드 프로젝트 설정

프로젝트 package 설정

https://docs.antora.org/antora/latest/install-and-run-quickstart/

Antora를 사용하려면 우선 node.js를 설치해야 한다.

node가 설치 되었으면 문서를 생성할 프로젝트를 만들고 해당 디렉터리로 이동해서 package.json을 만들고 다음과 같이 설정을 추가한 후 install 한다.

{
  "scripts": {
    "antora": "node npm/antora.js"
  },
  "dependencies": {
    "@antora/cli": "3.2.0-alpha.4",
    "@antora/site-generator": "3.2.0-alpha.4",
    "@antora/atlas-extension": "1.0.0-alpha.2",
    "@springio/antora-extensions": "1.11.1",
    "@springio/antora-xref-extension": "1.0.0-alpha.3",
    "@springio/antora-zip-contents-collector-extension": "1.0.0-alpha.8",
    "@asciidoctor/tabs": "1.0.0-beta.6",
    "@springio/asciidoctor-extensions": "1.0.0-alpha.10"
  }
}
npm install

playbook 설정

antora 빌드 프로젝트에서 취합할 대상 문서들에 대한 설정을 담은 antora-playbook.yml 파일을 만든다.

공식 사이트의 예제는 다음과 같다.
해당 예제로 site 문서를 만들어 볼 수 있으니 해당 내용을 사용해보자.

site:
  title: Antora Docs
  start_page: component-b::index.adoc 
content:
  sources: 
  - url: https://gitlab.com/antora/demo/demo-component-a.git
    branches: HEAD
  - url: https://gitlab.com/antora/demo/demo-component-b.git
    branches: [v2.0, v1.0]
    start_path: docs
ui: 
  bundle:
    url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
    snapshot: true

설정 파일을 살펴보면 index 페이지 설정과 문서를 가져올 git repository의 주소와 추가 설정(branch, path 지정)을 하고 template 파일에 대한 설정을 하고 있다.

취합할 대상 source 프로젝트들에 대한 git url/branch을 설정하고
source project 최상위 위치에 antora.yml 설정 파일이 위치하지 않은 경우엔 antora.yml 이 있는 위치를 start_path로 설정해 준다.
그리고 해당 path 하위에 nav.adoc는 왼쪽 메뉴를 구성하고 ROOT 및 named_module 디렉터리 하위에 각 메뉴 별 문서를 관리한다.

위 설정을 저장한 후 아래와 같이 실행해 본다.

npx antora --fetch antora-playbook.yml

antora 프로젝트의 /build/site 하위에 결과물이 생성된 것을 확인할 수 있다.

site 문서의 전체적인 디자인은 template 문서를 수정하여 빌드하면 된다.

source 프로젝트 설정

adoc 문서를 가져오는 source 프로젝트의 adoc 문서 구조는 다음과 같다

https://docs.antora.org/antora/latest/standard-directories/

예제 source 프로젝트를 살펴보면 어떤 모양으로 문서를 관리하면 되는지 알 수 있다.

https://gitlab.com/antora/demo/demo-component-a

https://gitlab.com/antora/demo/demo-component-b

기존 문서 빌드 위치 변경

기존엔 asciidoctor plugin을 사용하여 html 문서나 pdf 문서를 생성하였을 것이다.
단순히 antora로 변경하는 경우 asciidoctor 설정이 없이 문서 구조만 antora 구성에 맞게 변경하여 git repository에 push 되도록 수정하면 된다.

빌드 위치 변경

asciidoctor-maven-plugin 을 계속 사용해야 하는 경우 문서 생성 중간 단계(최종 htm을 생성하기 전 adoc 문서가 생성되는 단계)의 위치가 대상 위치가 git에 push 되어야 한다.

별도의 위치 설정을 하지 않으면

  1. ${basedir}/src/docs/asciidoc ( /src/main/asciidoc ) 위치의 adoc 문서를 빌드하여
  2. ${project.build.directory}/generated-docs (maven 기준 /target/generated-docs ) 위치에 html 결과물이 생성된다.
    https://docs.asciidoctor.org/maven-tools/latest/plugin/goals/process-asciidoc/#configuration

여기에 추가적으로 Spring REST Docs 을 사용하는 경우 별도의 위치 설정을 하지 않으면

  1. ${basedir}/src/docs/asciidoc (/src/main/asciidoc ) 위치의 adoc 문서를 지정한 위치로 복사하고 (내 경우엔 /target/refdocs 로 지정하였다.)
  2. ${project.build.directory}/generated-snippets (maven 기준 /target/generated-snippets )에 테스트 코드를 통해 생성된 코드 조각 adoc 문서가 생성되면
  3. 1의 adoc 문서가 2에 생성된 adoc 문서를 include 하도록 작성되어 있어 include처리를 한 최종 결과물이 ${project.build.directory}/generated-docs (maven 기준 /target/generated-docs ) 위치에 생성된다.

내 경우 최종 결과물인 html 문서 생성 위치만 /src/main/resources/static 으로 지정하였었다.
antora를 사용하는 경우 최종 결과물인 html 문서를 생성하기 전 단계의 adoc 문서가 git에 push 되어 있어야 한다.
따라서 임시 디렉터리인 ${project.build.directory}/refdocs , ${project.build.directory}/generated-snippets 위치를 git에 push 할 수 있는 위치로 대상 위치를 변경해 주면 된다.

내 경우 refdocs.build.directory 변수를 따로 선언하여 사용하였었기 때문에 아래처럼 설정을 변경하였다.

<properties>
    <refdocs.build.directory>src/main/antora</refdocs.build.directory>
    <asciidoctor.sourceDirectory>${refdocs.build.directory}</asciidoctor.sourceDirectory>
    <asciidoctor.outputDirectory>src/main/resources/static</asciidoctor.outputDirectory>
</properties>

또한 restdocs의 snippet 위치는 테스트 코드의 JUnitRestDocumentation 선언을 아래와 같이 설정하여 변경할 수 있다.

@Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/main/antora/[대상모듈]/partials");

snippet의 경우 partials 위치에 생성되면 site 문서 생성 시 해당 위치의 adoc 문서는 site 문서를 생성하지 않기 때문에 include 용으로만 사용할 수 있다.
https://docs.antora.org/antora/latest/partials-directory/

adoc 문서 디렉터리 구조 변경

antora가 생성하는 문서 사이트의 구성에 맞춰 문서 구조가 변경되어야 한다.
antora가 안내하는 문서 구조의 경우

  1. 지정된 위치 최상위 디렉터리에 antora.yml 문서가 있어야 하며
  2. modules 하위에 ROOT , 및 기타 모듈 디렉터리가 위치한다.
    1. 각 모듈 디렉터리마다 nav.adoc 문서가 위치한다. (이 nav 문서의 목록이 취합되어 antora site 문서의 왼쪽 메뉴 목록이 생성됨)
    2. pages 디렉토리 하위에 대상 문서가 위치한다.

적절히 구조를 변경하였고 antora.yml 을 설정해 준다.
(아래는 예시)

name: bluesky-boot
title: Bluesky Boot
version: 3.2.0
start_page: bluesky-boot.adoc
nav:
- modules/ROOT/nav.adoc
- modules/module-test/nav.adoc

추가적인 설정

각 source 프로젝트의 adoc문서에서 사용할 attribute를 선언할 수 있지만 antora 빌드 프로젝트의 playbook에서도 attribute를 지정할 수 있다.
이때 @ 선언 부분은 각 source 프로젝트에서 설정한 동일 attribute의 값을 override 할 수 있다는 의미이고
~ 선언은 각 source 프로젝트에서 설정한 동일 attribute의 값을 해제한다는 의미이다.
아래는 사용 예시이다.

asciidoc:
  attributes:
    page-team: Coco B@ db: graphical-peaks-pack.db test-server: http://localhost:9090/{db}
    chomp: all
    hide-uri-scheme: '@'
    page-pagination: ''
    tabs-sync-option: '@'
    figure-caption: ~

검색 설정

algolia를 사용하면 문서에 검색 기능을 추가할 수 있다.

https://www.algolia.com/

다만 오픈소스가 아니기 때문에 사용하기 전에 가격 정책을 확인해보아야 한다.

사용 장단점

antora 문서를 테스트해보니 아래와 같은 장단점이 있었다.

장점

  • 여러 곳의 문서를 취합해서 동일한 UI로 구성하에 제공 가능
  • 문서의 버전 별 관리가 용이 (git branch를 사용)
  • 검색도 추가 가능 (유료)

단점

  • source include 문제 (antora 대상 위치 밖의 java code include 같은 걸 구현하려면 너무 많은 작업이 필요)
  • antora를 사용하면 site 문서를 만들기 위해 기존 asciidoc 문서의 구조를 수정해야 함
    이로 인해 기존 asciidoc 문서 빌드와 병행 사용이 애매하게 됨
    (single page 문서 제공이 안되기 때문에 LLM RAG 학습시키기 애매했음)

include를 많이 사용하여 문서를 작성하는 경우엔 antora 사용에 대해 많은 고민이 필요하지 않을까 싶다.

Spring Boot의 경우 대략 아래와 같은 방식으로 해당 문제를 처리하였지만 사용하기엔 너무 복잡해서 관리하기 까다롭지 않을까 싶다.


Spring의 경우 source include를 어떻게 해결했을까?

앞서 단점에서 언급한 것처럼 antora 대상 위치 외부를 include 할 수 없다.

소스 코드 include 문제를 쉽게 해결하기는 현재로선 어렵고 대안으로 antora-collector-extension 을 사용할 수 있는 듯하다.
https://gitlab.com/antora/antora/-/issues/195
https://gitlab.com/antora/antora-collector-extension

spring boot의 경우 antora 프로젝트 빌드 시 antora-zip-contents-collector-extension 을 사용하여 해당 zip을 취합하는 듯하다.
https://github.com/spring-projects/spring-boot/blob/87094edab046e4002d3e8d9b4ba8d246a917dc0a/spring-boot-project/spring-boot-docs/src/docs/antora/antora.yml
https://github.com/spring-io/antora-zip-contents-collector-extension/

이를 위해 source 프로젝트에서 gradle 빌드 시 참조되는 source를 zip으로 만들어 generated/docs/antora-content , modules/ROOT/examples 를 거쳐
https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-docs/build.gradle#L296

호출 시 ROOT:example$java/org/springframework/boot/docs 에 위치하게 된다.

adoc 문서 내 include시엔 축약해서 사용할 수 있는 include-code 예약어를 제공하는 asciidoctor-extensions 를 사용한다.
https://github.com/spring-io/asciidoctor-extensions

아래와 같이 설정되어 있으면
https://raw.githubusercontent.com/spring-projects/spring-boot/87094edab046e4002d3e8d9b4ba8d246a917dc0a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/nosql.adoc

[[data.nosql.redis.connecting]]
=== Connecting to Redis

You can inject an auto-configured `RedisConnectionFactory`, `StringRedisTemplate`, or vanilla `RedisTemplate` instance as you would any other Spring Bean.
The following listing shows an example of such a bean:

include-code::MyBean[]

최초 대상은 아래에 위치한다.
https://github.com/spring-projects/spring-boot/blob/87094edab046e4002d3e8d9b4ba8d246a917dc0a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/nosql/redis/connecting/MyBean.java
(이 파일이 앞서 말한 antora-zip-contents-collector-extension )를 통해 최종적으로 antora 문서 위치 하위로 옮겨진다.

반응형