Summary

개발을 하다보면 소스코드를 문서화 해야하는 경우들이 종종 발생한다. 
내부적으로 볼 경우에는 주석을 잘달아서 소스코드를 직접 보면서 확인하면 되지만, 내부적으로 문서화 요청을 받거나 Wiki등록 혹은 외부에 공개해야하는 등의 경우에는 따로 문서를 만들어서 전달해야 한다. 이런 상황에서 각각의 클래스와 함수, 변수들을 정리하면서 문서로 만들면 아주 작은 프로젝트가 아닌이상 엄청난 노가다 작업을 필요로한다. 
하지만 세상은 많이 발전했고, 이런 작업을 대신해주는 소스코드 문서화 도구가 다양하게 존재한다. (사실 한참 전부터 존재했다.)
예를들어 C/C++은 doxygen, python은 Sphinx, Java는 Javadoc등, 그리고 이외에도 엄청 다양한 도구들이 존재한다.

하지만, 이 글에서는 Apple 소스코드의 문서화에 특화된 문서화 도구를 찾아보려고 한다. 그중에서도 Objective-c. (Swift는 추후에..)
Objective-C 기반이기 때문에 doxygen같은 C언어 관련 문서화 도구를 사용해도 되지만, 조금 더 욕심을 내서 애플 스타일 소스코드 문서화 형태로 만들어주는 도구를 사용해보도록 하자.
최근엔 다른 종류도 많이 나왔지만, 써본건 Appledoc, Headerdoc 두가지이다. 근데 Headerdoc은 애플 폐기 문서함에 들어가 있어서 왠지 쓰기 싫다.
그래서 Appledoc 으로 문서화 방법을 쓰려고 한다.
Appledoc은 기본 탬플릿을 제공하고, 커스터마이징된 탬플릿들도 찾아보면 몇가지 존재하고.. 일단 직접 문서를 보면서 직접 사용해보도록 하자.

Appledoc 설치

AppleDoc은 오픈소스로 공개되어있고, 스크립트를 실행하여 설치하거나 Homebrew를 사용하여 설치할 수 있다.
(스크립트를 이용하면 기본 탬플릿을 설치할 수 있고, Homebrew는 기본 탬플릿을 설치할 수 없다.)
#############
# Git clone #
#############
$ git clone git://github.com/tomaz/appledoc.git
#############################
# install appledoc - Script #
########## Case 1 ###########
#
$ sudo sh install-appledoc.sh
# 1-1. 릿 '-t default’
$ sudo sh install-appledoc.sh -t default
# 1-2. '-t {template_path}’ . (binary '-b {binary_path}')
$ sudo sh install-appledoc.sh -b /usr/bin -t ~/Library/Application\ Support/appledoc
###############################
# install appledoc - Homebrew #
########## Case 1 #############
# Homebrew (Homebrew 릿 )
$ brew install appledoc
설치가 완료되면, 'appledoc' 명령어를 입력해서 제대로 설치가 되었는지 확인해보자.
$ appledoc
appledoc version: 2.2.1 (build 1334)
Caught: AppledocException: At least one directory or file name path is required, use 'appledoc --help'

Appledoc 설치가 완료되면 바로 문서를 생성할 수 있다.
하지만, 바로 사용하려면 command에 여러가지 옵션들을 넣어서 실행을 해야 하기 때문에 프로젝트 내부에 문서화 옵션들을 미리 정의해놓고 사용하는 방법들을 알아보자.
미리 정의하지 않고 사용하면 아래처럼 사용해야 한다.
$ appledoc --project-name '' --project-company '' --template {릿 } --create-html --output ' ' .
# , .

프로젝트 내부 문서화 옵션 정의

문서화 옵션을 프로젝트내에 정의하는 방법은 plist 파일 추가, run script 추가 두가지 방법이 있다.
plist 파일을 생성하면 문서화 관련 옵션들을 plist로 쉽게 관리할 수 있는 장점이 있고,
run script를 사용하면 터미널을 열지 않고 문서화 타겟을 생성하여 빌드하면서 바로 문서를 생성할 수 있는 장점이 있다.
우선 두가지 모두 생성/사용 방법을 알아보자.
0. 공통
설정 가능한 전체 옵션이 궁금하다면 터미널에서 아래 명령어로 확인 가능하다.
$ appledoc --help
Usage: appledoc [OPTIONS] <paths to source dirs or files>
PATHS
-o, --output <path> Output path
-t, --templates <path> Template files path
--docset-install-path <path> DocSet installation path
-s, --include <path> Include static doc(s) at path
-i, --ignore <path> Ignore given path
-x, --exclude-output <path> Exclude given path from output
--index-desc <path> File including main index description
PROJECT INFO
-p, --project-name <string> Project name
-v, --project-version <string> Project version
-c, --project-company <string> Project company
--company-id <string> Company UTI (i.e. reverse DNS name)
OUTPUT GENERATION
-h, --create-html [b] Create HTML
-m, --create-markdown [b] Create markdown
-d, --create-docset [b] Create documentation set
-n, --install-docset [b] Install documentation set to Xcode
-u, --publish-docset [b] Prepare DocSet for publishing
--html-anchors <string> [*] The html anchor format to use in DocSet HTML.
--clean-output [b] Remove contents of output path before starting !!CAUTION!!
OPTIONS
--keep-intermediate-files [b] Keep intermediate files in output path
--keep-undocumented-objects [b] Keep undocumented objects
--keep-undocumented-members [b] Keep undocumented members
--search-undocumented-doc [b] Search undocumented members documentati
...
1. plist 사용
appledoc 오픈소스를 받으면 폴더내에 AppledocSettings.plist 라는 파일이 존재한다. 
직접 생성해도 전혀 문제는 없지만, 귀찮으니 있는 파일을 이용하도록 하자.
파일은 문서화를 하려는 프로젝트 root에 위치시키면 된다. (참고로 파일명은 AppledocSettings.plist 에서 바꿀 경우 설정을 변경해줘야 하므로 변경없이 쓰도록 하자)
plist파일은 터미널에서 명령어를 직접 입력할때 사용된다. (= 문서화를 터미널 명령어로 실행해야 한다)
아래 는 plist의 내부 모습이다. 각각 옵션값들이 어떤 역할을 하는지는 주석을 확인하자.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Paths -->
<key>--output</key> <!-- -->
<string>./help</string>
<key>--templates</key> <!-- 릿 ( 릿 ) -->
<string>~./appledoc-jazzy</string>
<key>--include</key> <!-- , -->
<array>
<string>Libs/Internal</string>
</array>
<key>--ignore</key> <!-- , -->
<array>
<string>Libs/External</string>
<string>*.framework</string>
<string>Pods</string>
</array>
<!-- Output generation -->
<key>--create-html</key> <!-- HTML -->
<true/>
<key>--create-markdown</key> <!-- markdown -->
<true/>
<key>--create-docset</key> <!-- Documentation set -->
<true/>
<key>--install-docset</key> <!-- DocSet Xcode -->
<true/>
<key>--clean-output</key> <!-- ( !!) -->
<true/>
<!-- Project Info -->
<key>--project-name</key> <!-- -->
<string>AppleDoc Example</string>
<key>--project-version</key> <!-- -->
<string>1.0.0</string>
<key>--project-company</key> <!-- -->
<string>Tez Lab.</string>
<key>--company-id</key> <!-- Bundle id -->
<string>kr.tez.appledoc.exam</string>
<!-- Options -->
<key>--keep-intermediate-files</key> <!-- -->
<true/>
<key>--print-information-block-titles</key> <!-- "Note:", "Warning:", "TODO:" -->
<true/>
<key>--preprocess-headerdoc</key> <!-- preprocess header -->
<true/>
<key>--repeat-first-par</key> <!-- Repeat first paragraph in member documentation -->
<true/>
<key>--merge-categories</key> <!-- Category class base class -->
<true/>
<key>--merge-category-comment</key> <!-- Category class comment base class -->
<true/>
<key>--keep-merged-sections</key> <!-- -->
<true/>
<key>--prefix-merged-sections</key> <!-- category class category prefix -->
<true/>
<key>--explicit-crossref</key> <!-- -->
<true/>
<key>--use-code-order</key> <!-- Order sections by the order specified in the input files -->
<true/>
<key>--docs-section-title</key> <!-- ( "Programming Guides") -->
<string>Tez Programming Guides </string>
<key>--exit-threshold</key> <!-- (0: Success!, 1: At least one warning was logged., 2: At least one error was logged., 3: At least one fatal error was logged., 250: Unhandled exception (Oops message). -->
<integer>2</integer>
<!-- MISCELLANEOUS -->
<key>--logformat</key> <!-- Log format [0-3] -->
<integer>3</integer>
<key>--verbose</key> <!-- ( ) [0-6, xcode] -->
<string>6</string>
</dict>
</plist>
2. RunScript
run script를 사용하려면 프로젝트 타겟에 script를 추가해주어야 한다.
기존 타겟에 추가를 할 경우 다른 스크립트들과 충돌날 수도 있기 때문에 새로운 타겟을 하나 생성해서 추가하는게 정신건강에 이로울 수 있다.
정신건강을 위해 먼저 타겟 추가 방법을 알아보자.
프로젝트 설정 -> 타겟 쭉 아래쪽에 ‘+’버튼 -> Cross-platform -> Aggregate 선택 -> 네이밍은 마음대로 하고 Finish를 해주면 새로운 타겟이 생성된다.
이제 스크립트 추가 방법을 알아보자.
프로젝트 설정 -> 생성한 타겟 선택 -> Build Phases 에 ‘+’ 버튼을 눌러서 New Run Script Phases로 스크립트를 넣을 수 있도록 추가해주자
생성된 스크립트 입력 공간에 아래 정보를 자신의 프로젝트 설정에 맞춰서 넣어주도록 하자.
#Appledoc Script
/usr/local/bin/appledoc \
--clean-output \
--output "./help" \
--templates "~/.appledoc" \
--ignore "*.framework" \
--create-html \
--no-create-docset \
--no-install-docset \
--project-name "${PROJECT_NAME}" \
--project-version "${PROJECT_VERSION}" \
--project-company "Tez Lab." \
--company-id "kr.tez.appledoc" \
--docset-platform-family "iphoneos" \
--keep-intermediate-files \
--keep-undocumented-objects \
--keep-undocumented-members \
--search-undocumented-doc \
--print-information-block-titles \
--preprocess-headerdoc \
--repeat-first-par \
--merge-categories \
--merge-category-comment \
--keep-merged-sections \
--prefix-merged-sections \
--explicit-crossref \
--use-code-order \
--docs-section-title "${PROJECT_NAME} Programming Guides " \
--exit-threshold 2 \
--no-warn-missing-output-path \
--no-warn-missing-company-id \
--warn-undocumented-object \
--warn-undocumented-member \
--warn-empty-description \
--warn-unknown-directive \
--warn-invalid-crossref \
--warn-missing-arg \
--warn-unsupported-typedef-enum \
--logformat xcode \
--verbose "2" \
.

문서 생성

plist를 사용한 경우와 script를 추가한 경우 모두 알아보자
1. plist 사용
위에서 언급한 것처럼 plist를 사용하면 터미널에서 명령어로 실행해 주어야 한다. (옵션을 모두 추가해 두었기 때문에 생각보다 복잡하지는 않다.)
$ appledoc .
이렇게 명령어를 입력하면 주르르륵 로그들이 나오고 문서가 생성된다.
2. Script 사용
script 를 추가해둔 경우 target을 생성해 두었기 때문에 xcode 내에서 문서화를 위해 생성한 타겟 생성 후 build를 해주면 지정해둔 경로에 문서가 생성된다.

Tip. 특정 폴더 추가/제거

1. 특정 폴더 제거
문서화를 하면서 특정 폴더를 제거하고 싶다면 ignore 옵션을 넣어주면 된다 (run script 기준)
(GenerateDoc 타겟의 Build Phases -> 작성해둔 Run script에서 제외할 경로들을 아래처럼 --ignore로 추가)
#Appledoc Script
...
--ignore "<path>" \
...
2. 특정 폴더 추가
문서화를 하면서 일부 폴더만 선택해서 문서화를 하고 싶다면, 마지막에 문서화 경로를 추가해주면 된다. (Run script 기준)
--include 옵션은 제대로 처리를 할 수 없어서 다른 방법으로 알아보자.
제거하기와 마찬가지로 Run script를 수정하는데, 일부 폴더 추가는 모든 폴더를 제외시키고 포함시킬 폴더를 전부 넣어주자. 아래 참조
#Appledoc Script
...
--ignore "." \
...
. \
<path1> \
<path2>

Custom Templates

appledoc은 내부 탬플릿을 제공하기는 하지만, 사용자가 맞춤형으로 탬플릿을 수정하여 사용할 수 있다.
여기서는 간단히 오픈소스로 공유되고 있는 두가지 탬플릿만 알아보도록 하자.
1. jazzy
jazzy 탬플릿은 조금 더 애플 문서에 맞춤형으로 생성이 되어있는 탬플릿이다. 기본 제공되는 것보다 구성이 더 깔끔하게 정리되있는 정도라고 생각하면 된다.
https://github.com/kaiinui/appledoc-template-jazzy
2. tez-custom
이건 그냥 기본 탬플릿에 objective-c code syntax 적용한 버전이다. 함수나 변수들을 볼때 조금 더 직관적으로 보기 위해서 github에 추가해 두었다.
기존 문서에서 코드 부분에 조금 더 색을 입히고 싶을때 사용하면 된다.
https://github.com/tezpark/appledoc-custom-template
ps. 코드내에 문서화 주석이 없으면 이 모든 작업이 아무 소용없다.


반응형