주의: [CPAN 모듈 작성 #2 - Module::Install를 이용한 자동 빌드 생성]의 가장 최근 판은 이곳에서 확인할 수 있습니다.
시작하며
CPAN 모듈로써 최소한의 외형적 요건을 갖추기 위해 필요한 것은 몇가지가 있습니다.
모듈 배포를 위해 필요한 파일 목록과 cpan 명령을 이용해서 자동으로 설치를
진행할 수 있도록 도와주는 자동화된 빌드 스크립트, 그리고 모듈의 정상 동작을
보장하기 위한 테스트 집합, CPAN 홈페이지에서 보여주기 위한 문서 등이 그것입니다.
이를 위해 필요한 작업은 지난 글을 통해 살펴보았습니다.
도움 모듈 및 스크립트를 이용해서 만든 뼈대 파일들을 이용해 자신의 모듈에
적합하게 필요한 부분은 더하고, 그렇지 않은 부분은 제외하거나 고치도록 합니다.
관련연구
준비물
Module::Install은 가능한 명료하고, 단순하고, 간단하게
CPAN 배포 모듈용 인스톨러를 만들수 있게 도와주는 모듈입니다.
ExtUtils::MakeMaker과 호환되며, 펄 5.004 이후의 버전에서
모두 실행 가능한 것이 특징입니다.
Module::Install을 이용하면 가능한 쉽게 CPAN 모듈을 작성할 수 있습니다.
- Module::Install – Standalone, extensible Perl module installer
Module::Install을 이용해서 만든 Makefile.PL의 예시입니다:
Makefile.PL:
use inc::Module::Install;
# Define metadata
name 'Your-Module';
all_from 'lib/Your/Module.pm';
# Specific dependencies
requires 'File::Spec' => '0.80';
test_requires 'Test::More' => '0.42';
recommends 'Text::CSV_XS'=> '0.50';
no_index 'directory' => 'demos';
install_script 'myscript';
WriteAll;
디렉터리 구조
Module::Starter를 이용해서 뼈대를 만들었다면 자동으로 생성된
디렉터리 및 파일 구조는 다음과 같을 것입니다:
Log-Simple-Color
Log-Simple-Color/lib
Log-Simple-Color/lib/Log/Simple
Log-Simple-Color/lib/Log/Simple/Color.pm
Log-Simple-Color/t
Log-Simple-Color/t/perlcritic.t
Log-Simple-Color/t/pod-coverage.t
Log-Simple-Color/t/00.load.t
Log-Simple-Color/t/pod.t
Log-Simple-Color/.cvsignore
Log-Simple-Color/Makefile.PL
Log-Simple-Color/Build.PL
Log-Simple-Color/Changes
Log-Simple-Color/README
Log-Simple-Color/MANIFEST
실제로 모듈 구현과 관련한 디렉터리는 Log-Simple-Color/lib이며
나머지는 모두 배포 및 테스트와 상관있는 요소입니다.
다음은 각 파일의 목록과 그에 대한 간략한 설명입니다:
Log-Simple-Color/lib : 모듈 저자가 구현한 파일을 담는 디렉터리
Log-Simple-Color/lib/Log/Simple : 이름 공간을 위해 자동 생성
Log-Simple-Color/lib/Log/Simple/Color.pm : Log::Simple::Color 모듈
테스트 집합은 모두 Log-Simple-Color/t 하부에 존재합니다.
이 디렉터리에 존재하는 파일 중 확장자가 .t 인 파일은 모두
make test 또는 ./Build test 수행시 자동으로 모듈의 동작을
점검하기 위한 테스트 파일입니다.
다음은 각 파일의 목록과 그에 대한 간략한 설명입니다:
Log-Simple-Color/t : 자동으로 테스트하기 위한 파일을 보관하는 디렉터리
Log-Simple-Color/t/perlcritic.t : 작성한 모듈이 PBP 규칙을 따르는지 점검
Log-Simple-Color/t/pod-coverage.t : 작성한 모듈의 공개 API 가 문서를 가지는지 점검
Log-Simple-Color/t/00.load.t : 작성한 모듈의 적재 성공 여부를 점검
Log-Simple-Color/t/pod.t : 작성한 모듈에서 POD 문서 생성 성공 여부 점검
배포와 관련한 파일 중 자동 빌드를 위한 파일 목록은 다음과 같습니다:
Log-Simple-Color/Makefile.PL : make 또는 dmake, nmake 을 위한 Makefile 생성기
Log-Simple-Color/Build.PL : make가 없는 환경을 위한 Build.PL 생성기
Log-Simple-Color/MANIFEST : 배포용 릴리즈 파일을 생성시 포함할 파일 목록
CPAN은 배포와 관련한 파일 중 여러분의 모듈을 사용자가 수동으로 다운로드 받은 후
직접 설치시 도움이 될 만한 문서도 포함하는 것을 권장합니다.
물론 이 문서 파일에 의미있는 내용을 넣을지 여부는 개발자에게 달려있습니다.
다음은 배포시 필요한 문서 파일 목록입니다:
Log-Simple-Color/Changes : 릴리즈 별로 모듈의 변경사항을 명시하는 문서
Log-Simple-Color/README : 사용자가 제일 먼저 읽기를 바라는 문서
그외 개발의 편의를 돕기 위한 파일 목록은 다음과 같습니다:
Log-Simple-Color/.cvsignore : CVS 버전 관리 툴을 사용할 때 무시할 파일 목록
구현
Build.PL 제거
Log::Simple::Color 모듈은 perl ./Build.PL를 이용한 자동 빌드를
지원하지 않을 것이므로 사용하지 않을 Build.PL 파일을 제거합니다.
Build.PL을 사용할지 Makefile.PL을 사용할지,
또는 두 방법 모두 지원할 것인지는 전적으로 모듈 저자에게 달려있습니다:
$ rm Build.PL
MANIFEST.SKIP 추가
MANIFEST 파일은 배포에 필요한 파일을 명시적으로 기록하는 용도로 사용합니다.
반대로 MANIFEST.SKIP 파일을 이용하면
배포시 넣지 않을 파일을 명시적으로 기록할 수 있습니다.
버전관리와 관련한 파일이나, 임시 파일등을 기록해두면 편리합니다.
MANIFEST.SKIP 파일의 예제는 다음과 같습니다.
대부분의 경우 비슷한 MANIFEST.SKIP 파일을 가지므로 가장 아래 부분에
모듈 이름을 명시한 부분만 자신의 모듈에 맞게 적당하게 변경해주면 됩니다:
MANIFEST.SKIP:
# Avoid version control files.
\bRCS\b
\bCVS\b
,v$
\B\.svn\b
\B\.cvsignore$
# Avoid Makemaker generated and utility files.
\bMakefile$
\bblib
\bMakeMaker-\d
\bpm_to_blib$
\bblibdirs$
^MANIFEST\.SKIP$
# Avoid Module::Build generated and utility files.
\bBuild$
\bBuild.bat$
\b_build
# Avoid Devel::Cover generated files
\bcover_db
# Avoid temp and backup files.
~$
\.tmp$
\.old$
\.bak$
\#$
\.#
\.rej$
# Avoid OS-specific files/dirs
# Mac OSX metadata
\B\.DS_Store
# Mac OSX SMB mount metadata files
\B\._
# Avoid archives of this distribution
# 자신의 모듈에 맞게 수정합니다.
\bLog-Simple-Color-[\d\.\_]+
테스트 집합 작성
Perl::Critic 테스트 회피
펄 프로그램을 작성시 Perl::Critic 모듈이 제안하는
Perl Best Practices 권고를 따르는 것은 좋은 습관입니다.
그래서 Module::Starter 모듈은 디렉터리 구조를 생성할 때
Test::Perl::Critic 모듈을 사용해서 작성한 코드가
커뮤니티가 권고하는 규칙을 잘 지키는지 점검하는 t/perlcritic.t 테스트를
자동으로 추가합니다.
대부분의 경우 t/perlcritic.t이 알려주는 메시지는 매우 유용하며
견고한 펄 프로그램을 작성할 수 있게 도와줍니다.
하지만 시스템 환경에 따라 선별적으로 모듈을 적재하기 위해서
eval을 써야 하는 상황이라던가, 또는 그렇지 않다하더라도
좀 더 유연한 환경에 편하게 코드를 작성하고 싶을 수도 있습니다.
이 경우는 해당 테스트를 강제로 제외해서 테스트 실패를 막을 수 있습니다.
해당 테스트 파일을 지우거나 확장자를 .t가 아닌 다른 것으로 변경하면
간단히 테스트를 자동으로 수행하지 않도록 할 수 있습니다:
$ mv t/perlcritic.t t/perlcritic.t.skip
자동 테스트 목록에서 테스트 파일을 뺐더라도
언제든지 명령줄에서 prove 명령을 통해 수동으로 테스트할 수 있습니다:
$ prove t/perlcritic.t.skip
테스트 파일 추가
작성한 모듈의 동작을 점검할 수 있는 두 가지 테스트 파일을 추가합니다.
파일의 이름의 아스키문자 순서대로 자동으로 테스트를 수행하므로
먼저 테스트하기를 원하는 파일은 작은 숫자를 붙이도록 합니다.
의존성있는 모듈을 제대로 적재할 수 있는지 점검하는
t/01.dependency.t 파일은 다음과 같이 구성합니다:
t/01.dependency.t:
use Test::More tests => 3;
BEGIN {
use_ok( 'Log::Simple::Color' );
}
diag( "Testing Log::Simple::Color $Log::Simple::Color::VERSION" );
SKIP: {
skip( 'Term::ANSIColor is not required for win32 systems', 1 ) if $^O eq 'MSWin32';
use_ok( 'Term::ANSIColor' );
}
SKIP: {
skip( 'Win32::Console is not required for non win32 systems', 1 ) if $^O ne 'MSWin32';
use_ok( 'Win32::Console' );
}
모듈의 동작을 점검하는 t/10.logging.t 파일은 다음과 같이 구성합니다:
t/10.logging.t:
use strict;
use warnings;
use Test::More tests => 6;
use Log::Simple::Color;
diag( "Testing Log::Simple::Color API" );
my $log = Log::Simple::Color->new;
isa_ok( $log, 'Log::Simple::Color', 'instance check' );
is( $log->VERSION, '0.0.1', 'version check' );
is( $log->level, 'info', 'log level check' );
is( $log->debug('This is a debug message'), undef, 'debug is lower level than info' );
is( $log->level('unknown level'), 'info', 'unknown log level must be info level' );
is( $log->level('debug'), 'debug', 'set log level to debug' );
MANIFEST
앞에서 배포에 필요한 파일을 추가하거나 제거, 또는 이름을 변경했으므로
변경사항에 맞게 MANIFEST 파일을 갱신하도록 합니다:
제거할 항목:
Build.PL
t/perlcritic.t
추가할 항목:
MANIFEST.SKIP
t/01.dependency.t
t/10.logging.t
t/perlcritic.t.skip
변경 후의 MANIFEST 파일은 다음과 같습니다:
MANIFEST:
Changes
MANIFEST
MANIFEST.SKIP
Makefile.PL
README
lib/Log/Simple/Color.pm
t/00.load.t
t/01.dependency.t
t/10.logging.t
t/perlcritic.t.skip
t/pod-coverage.t
t/pod.t
Makefile.PL 재구성
ExtUtils::MakeMaker 또는 Module::Install 모듈을 이용해서
Makefile.PL을 생성하면 사용자는 명령줄에서 다음 명령을 사용해서
여러분의 모듈을 빌드하고, 테스트 한 후 모든 것이 성공적이라면
자동으로 설치까지 할 수 있습니다:
$ perl Makefile.PL
$ make
$ make test
$ sudo make install
GNU make가 아니더라도 dmake, nmake 등 시스템에 설치되어 있는 make
유틸리티를 사용해서 자동으로 펄 모듈을 빌드 및 테스트, 설치할 수 있습니다.
Log::Simple::Color 모듈을 위해 만든 Makefile.PL은 다음과 같습니다:
Makefile.PL:
use 5.008_001;
use strict;
use inc::Module::Install 0.77;
# Define metadata
name 'Log-Simple-Color';
license 'perl';
author 'Keedi Kim - 김도형 <keedi@cpan.org>';
all_from 'lib/Log/Simple/Color.pm';
# Specific dependencies
perl_version '5.008_001';
requires 'version' => 0;
requires 'File::Spec' => '0.80';
requires 'Module::Install' => '0.77';
requires 'Term::ANSIColor' => '1.12' unless win32;
requires 'Win32::Console' => '0.09' if win32;
requires 'Perl6::Say' => '0.12' if $] < 5.010;
test_requires 'Test::More' => '0.42';
#homepage '';
#bugtracker '';
#repository '';
WriteAll;
모듈의 문서화
Changes 내용 추가
Changes 파일과 README 파일에 꼭 의미있는 정보를 기입해야하는 것은 아니지만,
여러분의 모듈 사용자들은 아마도 이 파일을 통해 설치하기 전에 모듈의 변경사항이나
중요한 API 사용법이나 설치 방법 등을 확인하고 싶어할 것입니다.
Changes 파일은 버전 업 할때마다 변경된 사항을 정리하도록 합니다.
Log::Simple::Color 모듈의 변경사항은 다음과 같습니다:
Changes:
Revision history for Log-Simple-Color
0.0.1
Wed Dec 31 10:48:10 KST 2008
Initial release.
새로운 버전 정보를 추가할 때는 0.0.1 보다 아랫부분에 추가하지 말고
위에 추가해서 사용자가 쉽게 변경사항을 추적할 수 있도록 배려합니다:
Changes:
Revision history for Log-Simple-Color
0.0.2
Fri Jan 2 18:49:55 KST 2009
Added changing color API Bug #4
Fixed windows install failure Bug #12
0.0.1
Wed Dec 31 10:48:10 KST 2008
Initial release.
README 내용 추가
README 파일은 그 이름처럼 모듈 사용자가
가장 처음 열어 볼 확률이 높은 파일입니다.
이 파일에는 모듈에 대한 개략적인 설명 뿐만 아니라,
설치 방법, 알려진 버그, 라이센스 등과 관련한 정보가
들어있는 것이 관례입니다.
이 파일 역시 Changes 파일 처럼 수동으로 생성할 수도 있지만
Log::Simple::Color 모듈의 POD 문서를 꼼꼼하게 작성한다면
이 문서를 그대로 이용하는 것도 좋은 방법입니다.
README 파일을 자동으로 생성하려면 Makefile.PL의
적당한 위치에 다음 내용을 추가합니다:
Makefile.PL:
...
if ( -e 'MANIFEST.SKIP' ) {
system( 'pod2text lib/Log/Simple/Color.pm > README' );
}
...
lib/Log/Simple/Color.pm 에 POD 추가
마지막으로 대부분의 CPAN 모듈이 그러하듯이
lib/Log/Simple/Color.pm 파일 내부에 POD 문서도 추가해야 합니다.
모듈 내부에 작성한 POD 문서를 이용해서 CPAN에서 그 내용을 열람하거나,
설치후 perldoc 을 통해 참고할 수 있으므로 번거롭지만 꼼꼼하게
문서를 작성하는 것은 중요한 일입니다.
Module::Starter 모듈이 대부분의 외형을 작성해주기 때문에
처음부터 작성할 필요없이 해당 섹션에 필요한 내용만 추가하면 됩니다.
또한 t/pod.t와 t/pod-coverage.t 테스트는 모듈에 있는 POD 문서가
올바른 문법을 지켜서 작성되었는지, 공개 API 에 대해서 명시적으로
문서화를 하고 있는지 점검해주므로 작성 중간중간에 이들 테스트를 활용해서
올바르게 문서화를 하고 있는지 확인하면 편리합니다.
물론 POD 관련 테스트를 회피하려면 t/perlcritic.t 테스트를 회피하듯이
테스트 목록에서 제거할 수 있지만 그다지 좋은 생각은 아닙니다.
설치 및 배포
완성한 모듈을 CPAN에 올리기 위해서는 CPAN이 요구하는 형식에 맞게
모듈이름과 버전 번호를 명시해서 압축 파일을 만들어야 합니다.
또한 이 압축 파일에는 지금까지 작업한 관련있는 파일이 모두 들어가야합니다.
Makefile.PL을 이용해서 Makefile을 생성하면 릴리스와 관련한
일련의 작업을 자동으로 해주므로 특별한 예외사항이 없다면
이부분에 대해서 고민할 필요가 없습니다.
명령줄에서 다음 명령을 실행하면 자동으로 CPAN에 업로드하기 위한
압축 파일을 생성합니다:
$ perl Makefile.PL
$ make dist
물론 이렇게 제작한 펄 모듈을 꼭 CPAN에 업로드해야 하는 것은 아닙니다.
사내 배포용으로 사용할 수도 있고, 개인용으로 사용할 수도 있습니다.
(하지만 CPAN에 업로드 하는 편이 훨씬 낫다는 것을 곧 깨달을 것입니다. ![]()
어느 쪽을 선택하든 일련의 과정을 거친 펄 모듈은 완전한 자동 빌드 환경과
테스트 환경, 문서를 가지고 있는 CPAN에 있는 모듈과 다를 바가 없으므로
펄에 익숙한 대부분의 사용자들은 거부감 없이 여러분의 모듈을 즐길 것입니다.
정리하며
지금까지 CPAN 모듈을 작성하는 방법을 알아보았습니다.
사실 package 지시어를 이용해서 특정 기능을 수행할 수 있는
API를 제공한다면 어떤 형태든 모두 펄 모듈이라고 할 수 있습니다.
하지만 관례적으로 제대로 모양새를 갖춘 펄 모듈은
CPAN 모듈이라고 생각하기 때문에 어짜피 제작할 펄 모듈이라면
CPAN 에서 요구하는 최소한의 요건을 갖추는 것이 좋습니다.
CPAN이 요구하는 몇가지 사항(문서화, 자동 빌드, 테스트 집합)은
비단 펄로 개발 할 때 뿐만 아니라 다른 언어로 개발할 때 역시
도움이 될 수 있는 좋은 참고 자료가 될것입니다.
관련 글

This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 2.0 Korea License.