심볼파일에 소스 인덱싱을 하기 위해서 해야할 건 다 했는데 인덱싱이 안된다. (프로그램 설치 및 Path 지정, 파일 수정 등)
"zero source files found" 에러만 계속 뱉어내서 3일을 헤매다가 펄은 모르지만 그냥 분석해보기로 결정.
svnindex.cmd 는 svn.pm 을 호출하므로 이 파일을 열어봤다.
일반적으로 한글 지원을 위해 수정해야 하는 것으로 알고 있는 부분은 Path: 와 Revision: 이다.
m/^Path:[\s\t]*(.*)$/i
m/^Revision:[\s\t]*(\d*)$/i
이 부분을 다음과 같이 수정해야 한다.
m/^Path|^경로:[\s\t]*(.*)$/i
m/^Revision|^리비전:[\s\t]*(\d*)$/i
[m/정규표현식/i]는 다른 언어에서도 사용하는 방식의 정규표현식이라 한눈에 알아봤다.
'^'는 라인의 시작, '$'는 라인의 끝과 매치된다. (http://www.rubular.com/ 에서 아래쪽에 나오는 원문으로 확인 가능)
예전에는 [|경로, |리비전] 처럼 '^'를 추가하지 않아도 됐는데, 어느 순간부터 안 되어서 내가 수정했다.
그럼 이 정규표현식을 사용할 원문은 어디서 가져올까?
분명 svn.exe 명령어를 사용한 결과일 것이다.
$$self{'SVNCMD'} = "svn.exe";
...
open($hProcess, "$$self{'SVNCMD'} info -R \"$SourceRoot\"|")
이걸로 해당 명령어는 [svn.exe info -R "소스루트경로"] 임을 알 수 있다.
(사실 "|"가 뭔지 몰라서 넣어봤지만 명령 구문이 올바르지 않다고 한다)
커맨드창에서 해당 명령어를 입력해보니 정보가 쭉 나오는데, 다 볼 필요는 없을 것 같아서 Ctrl+C로 중단했다.
파일 하나의 출력을 보니 다음과 같았다.
경로: relative_path\source_file.c
이름: source_file.c
작업 사본의 루트 경로: C:\absolute_path
URL: http://source_server_url/svn/XXX/trunk/relative_path\source_file.c
저장소 루트: http://source_server_url/svn/XXX
저장소 UUID: 00000000-0000-0000-0000-000000000000
리비전: 863
노드 종류: 파일
스케쥴: 일반
마지막 수정 작업자: ldevil63
마지막 수정 리비전: 852
마지막 수정 일자: 2012-12-06 17:23:34 +0900 (2012-12-06, 목)
마지막 내용 수정 일자: 2013-01-03 10:51:37 +0900 (2013-01-03, 목)
체크섬: 28ea7d26eac7015034cc15075cd11faa630f5646
여기서 출력 결과가 한글이기 때문에 위에서 처럼 정규표현식 구문을 수정했던 것이다.
svn.exe가 영문이라면 경로:는 Path:로, 리비전:은 Revision:으로 출력된다.
pdb 파일을 텍스트 에디터로 열어서 확인해보면 소스 경로는 절대경로로 입력되어 있다. (srctool.exe를 사용해도 확인 가능)
하지만 여기서 찾은 경로 값은 상대경로이다.
예전에 잘 되었을 때의 pdb 파일을 열어보니 다음과 같은 식으로 입력되어 있다.
C:\absolute_path\relative_path\source_file.c*http://source_server_url/*svn/XXX/trunk/relative_path\source_file.c*863
이것도 절대경로...
그런데 svn.pm에서 위 부분을 삽입하는 부분은 조금 이상하다.
@{$$self{'FILE_LOOKUP_TABLE'}{lc $LocalFile}} = ( { }, "$LocalFile*$FileRepository*$FileRelative*$FileRevision");
앞 부분은 잘 모르겠고, 뒤의 변수들 값을 찾아보니, 다른 건 다 일치하는데 $LocalFile은 상대경로였다.
if ( $curline =~ m/^Path|^경로:[\s\t]*(.*)$/i ) {
$LocalFile = lc $1;
...
}
참고로 $1은 정규표현식에서 매칭된 문자열의 첫번째 괄호 부분이다.
따라서 제일 처음의 "relative_path\source_file.c" 이다.
절대경로로 변경해서 해보려고 svn.pm 파일을 수정하였다. (일부만 발췌)
my $LocalFile;
my $LocalFilePathRelative;
my $LocalFilePathAbsolute;
...
if ( $curline =~ m/^(Path|경로):[\s\t]*(.*)$/i ) {
$LocalFilePathRelative = lc $2;
...
# Parse Working Copy Path
if ( $curline =~ m/^(Working Copy Root Path|작업 사본의 루트 경로):[\s\t]*(.*)$/i ) {
$LocalFilePathAbsolute = lc $2;
$LocalFile = $LocalFilePathAbsolute . "\\" . $LocalFilePathRelative;
}
}
절대경로로 변경하고 나니 잘된다 ㅋㅋ
=========================================================================================================================================
하다보니 또 안되는 경우가 생겼다.
svn info 명령을 실행하는 위치가 작업 사본의 루트이면 경로: 의 값이 상대경로로 나오고, 그 외에는 다음처럼 절대경로로 나온다.
경로: C:\absolute_path\relative_path\source_file.c
이름: source_file.c
작업 사본의 루트 경로: C:\absolute_path
URL: http://source_server_url/svn/XXX/trunk/relative_path\source_file.c
저장소 루트: http://source_server_url/svn/XXX
저장소 UUID: 00000000-0000-0000-0000-000000000000
리비전: 863
노드 종류: 파일
스케쥴: 일반
마지막 수정 작업자: ldevil63
마지막 수정 리비전: 852
마지막 수정 일자: 2012-12-06 17:23:34 +0900 (2012-12-06, 목)
마지막 내용 수정 일자: 2013-01-03 10:51:37 +0900 (2013-01-03, 목)
체크섬: 28ea7d26eac7015034cc15075cd11faa630f5646
절대경로의 루트부분이 중복되어 입력되어 다음과 같은 이상한 경로가 입력된다.
C:\absolute_pathC:\absolute_path\relative_path\source_file.c
따라서 소스 위치가 아닌 곳에서 소스 인덱싱을 하는 경우에는 정상동작을 하지 않을 것이다.
아래와 같이 작업 사본의 루트 경로 위치에 따라 입력하도록 svn.pm을 다시 수정하였다.
# Parse Working Copy Path
if ( $curline =~ m/^(Working Copy Root Path|작업 사본의 루트 경로):[\s\t]*(.*)$/i ) {
$LocalFilePathAbsolute = lc $2;
if ( index ($LocalFilePathRelative, $LocalFilePathAbsolute) != -1) {
$LocalFile = $LocalFilePathRelative;
} else {
$LocalFile = $LocalFilePathAbsolute . "\\" . $LocalFilePathRelative;
}
}
첨부된 파일은 다시 수정된 svn.pm 파일이다.
이상 기록 끝.
=========================================================================================================================================
다른 회사에서 해봤더니 또 안되는 경우가 발생!
삽질 엄청 하다가 알아낸 결론은... GIt 때문이었다.
망할 Git 의 bin 디렉토리에 perl.exe가 있어서 발생한 오류 ㅠ_ㅠ
Git 을 설치했다면 Path에 ActivePerl 의 경로가 앞에 오도록 설정해주면 된다.