'파일집합'에 해당되는 글 2건

  1. 2008.12.05 Buildr : 파일집합 복사하기
  2. 2008.12.01 Buildr : 파일 집합 선택

지난 글에서 FileList와 glob 패턴을 이용해서 파일 집합을 선택하는 방법을 알아보았습니다. 그럼 이렇게 선택된 파일들을 다른 디렉토리에 복사하는 방법을 살펴보겠습니다. 
음... web 디렉토리내의 *.html 및 *.gif 파일들을 target/htdocs 디렉토리로 한번 복사해볼까요?

FileList['web/**/*.{html,gif}'].exclude('web/WEB-INF').each do |file|
   cp file, 'target/htdocs'
end

FileList의 파일 목록을 each로 순회하면서 cp하고 있습니다. 오 쉽군요. 그러나........
cp 메소드는 파일을 타겟 디렉토리로 복사해주긴 하는데 경로를 유지하지는 않습니다. 말하자면 web/AA/a.html 파일과 web/AA/BB/b.html 파일은 각각 target/htdocs/a.html과  target/htdocs/b.html로 복사됩니다. 경로는 다르지만 파일명이 같다면 뒤에 복사된 파일이 먼저 파일을 덮어쓰게됩니다.

우리가 원하는 건 web/AA/a.html 파일은 target/htdocs/AA/a.html 로 복사되고 web/AA/BB/b.html은 target/htdocs/AA/BB/b.html로 복사되는 것입니다.

FileList['web/**/*.{html,gif}'].exclude('web/WEB-INF').each do |file|
  target = file.sub('web','target/htdocs')
  mkdir_p File.dirname(target)
  cp file, target
end

원래 파일 경로 'web/AA/BB/b.html'에서 'web'을 'target/htdocs'로 바꾼 뒤 타켓 디렉토리를 만들고(mkdir_p) 거기에 파일을 복사해주었습니다. 그런데 좀 지저분하군요. 깔끔한 방법이 없을까요?

제가 찾아낸 방법은 buildr에서 제공하는 filter() 메소드를 이용하는 것입니다.

filter('web').into('target/htdocs').include('**/*.html', '**/*.gif').exclude('WEB-INF/**/*').run

원래 buildr의 filter는 Maven의 리소스 필터처럼 리소스 파일의 내용을 필터링하기 위한 목적으로 만들어진 것입니다만, 이런식으로 filter()를 한 디렉토리 내의 파일집합을 다른 디렉토리로 복사하는데 이용할 수 있습니다.

참고로 filter는 내부적으로 File.fnmatch를 이용하는데 File.fnmatch가 받는 패턴은 { } 표현을 지원하지 않는다고 문서에 나옵니다. 예를 들어 filter()의 include, exclude 메소드에 '**/*.{html,gif}' 패턴을 넘겨주면 *.html이나 *.gif를 찾는 것이 아니라 "{html,gif}"라는 확장자를 가진 파일을 찾게 됩니다.
또한 FileList[].exclude('web/WEB-INF')와 filter().exclude('WEB-INF/**/*')도 약간 다른 것을 볼 수 있습니다. 패턴이 제대로 적용되는지 반드시 테스트해보시기 바랍니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Build&Deploy > Buildr' 카테고리의 다른 글

Buildr : 리소스 교체  (3) 2008.12.09
Buildr : 리소스 필터링  (0) 2008.12.09
Buildr : 파일집합 복사하기  (0) 2008.12.05
Buildr : 파일 집합 선택  (0) 2008.12.01
Buildr : 의존성(dependencies) 설정하기  (4) 2008.11.19
Buildr : 컴파일 옵션 설정하기  (2) 2008.11.18
Posted by 에코지오

댓글을 달아 주세요

루비 'fileutils.rb' 라이브러리에 보면 FileUtils 모듈이 있습니다. FileUtils에는 파일/디렉토리를 다루기 위한 기본적인 유틸리티 메소드가 정의되어 있는데, 메소드명은 유닉스에서 우리가 쓰던 명령과 유사합니다. cp(), mkdir(), rm(), mv() 처럼요 ....

rake는 기본적으로 이 FileUtils 모듈을 include하고 있기 때문에 rake에 기반을 두고 있는 buildr에서도 거리낌없이 FileUtils의 메소드를 사용할 수 있습니다.

mkdir 'build/myproject/bin'
cp 'src/abc.xml.dev' 'build/myproject/bin/abc.xml'

Ant에서는 <copy>, <mkdir>, <delete>, <move> 등의 코어 타스크를 이용하여 이런 작업을 처리했죠.( Maven은 maven-antrun-plugin 플러그인을 통해서 ant의 타스크를 간접 호출해서 작업을 합니다. 좀 귀찮죠)

 <copy file="myfile.txt" tofile="mycopy.txt"/>

작업할 파일이 하나가 아니면 어떡할까요? Ant에서는 파일의 집합을 FileSet으로 표현합니다.
예를들어 소스 디렉토리 내의 java 소스를 제외한 파일들을 빌드 디렉토리로 복사하는 작업은 아래처럼 정의할 수 있습니다. 여기서 **/*.java 와 같은 경로 표현은 Ant에서 정의한 패턴입니다. Ant style 경로패턴이라고도 하죠(?)

  <copy todir="../build/classes">
    <fileset dir="src_dir">
      <exclude name="**/*.java"/>
    </fileset>
  </copy>
            또는
  <copy todir="../build/classes">
    <fileset dir="src_dir" excludes="**/*.java"/>
  </copy>

rake/buildr에는 Ant의 FileSet에 대응하는 Rake::FileList 클래스가 있습니다. FileList는 주어진 glob 패턴과 매치되는 파일의 목록을 리턴합니다.

FileList['src_dir/**/*.java']
   => src_dir 디렉토리 내의 모든 .java 파일 목록 리턴

FileList['web/**/*'].exclude('**/*.jsp','web/WEB-INF') 
   => web 디렉토리 내의 .jsp 파일 및 WEB-INF 디렉토리를 제외한 모든 파일 목록 리턴

FileList와 비슷한 것으로 Dir.glob()이 있는데요, FileList는 CVS, .svn, .bak 등의 디렉토리/파일을 기본적으로 목록에서 제외하는 반면 Dir.glob()은 그런 것들도 포함해서 리턴합니다. 그러니까 빌드스크립트에서는 Dir.glob() 보다는 FileList를 쓰는게 좋습니다.

참고적으로 File.fnmatch(패턴,파일경로) 메소드가 있습니다. 이 메소드는 주어진 파일의 경로가 지정된 패턴에 부합하는지 판단합니다. FileList[]나 Dir.glob()과 마찬가지로 패턴은 glob 형식입니다.
주의하실 점은 FileList[패턴]의 패턴, FileList[].exclude(패턴)의 패턴, File.fnmatch(패턴)의 패턴이 조금씩 차이가 있는 것 같다는 겁니다. 반드시 적용전 테스트를 해보셔야 합니다. 그리고 File.fnmatch가 패턴은 { } 표현을 지원하지 않습니다. 즉 File.fnmatch()에서 'A.html' 파일은 '**/*.{html,gif}' 패턴과 매치하지 않습니다.

내용이 길어져서 파일집합에서 원하는 파일들만 복사하는 작업과 리소스 파일 치환에 대한 예제는 다음글로 넘깁니다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 에코지오

댓글을 달아 주세요



티스토리 툴바