사용자 도구

사이트 도구


kb:perforcetrigger

Perforce Trigger

퍼포스 트리거는 퍼포스에서 각종 이벤트가 발생했을 때, 지정된 스크립트 또는 프로그램을 실행해서 그 결과로 작업의 흐름을 조정하는 데 사용한다.

기본적으로 해당 스크립트가 0을 반환하면, 이벤트가 계속 실행된다. 0이 아닌 값을 반환하면 이벤트는 중단된다. 실패시, 해당 스크립트의 출력은 퍼포스 에러로 간주되어 UI에 표시된다.

트리거의 종류

http://www.perforce.com/perforce/doc.current/manuals/cmdref/triggers.html

종류 발생 시점 사용처
change-submit 체인지 리스트를 서브밋시 최초 발생.
체인지 리스트 목록만 전송되고, 파일 내용은 아직 전송되기 전
체인지 리스트 설명문이 충분한지 검사.
체인지 리스트 파일 목록을 검사.
change-content 체인지 리스트를 서브밋시 발생.
체인지 리스트 내용과 파일은 전송 완료, 그러나 아직 커밋은 하지 않음.
파일 내용을 검사
change-commit 체인지 리스트 내용과 파일 모두 커밋 후 발생.
shelve-submit
shelve-commit
shelve-delete
fix-add
fix-delete
form-save
form-out
form-in
form-delete
form-commit
archive
auth-check
auth-check-sso
auth-set
service-check

보시다시피 뭔가 많은데, change-xxx 시리즈 말고는 어디 써야할지 별 느낌이 없다.

설정

스크립트를 작성 후 “p4 triggers” 명령을 통해 설정할 수 있다.

my_script_name change-submit //depot/... "somewhere\python somewhere\my_trigger_name.py %changelist%"

인수 목록은 퍼포스 매뉴얼을 체크하시오. 근데 뭐, 스크립트 내부에서 액세스할 수가 있어서 changelist 말고는 별로 필요없을 듯?

샘플

그냥 커맨드 라인으로 처리하는 것보다는 P4Python 같은 패키지를 이용하는 것이 도움이 된다. 아래의 샘플들은 P4Python 패키지를 이용했다.

1. 체인지 리스트 설명문 검사

유저가 입력한 설명문이 특정 포맷과 일치하는가?

import sys
import sre_compile
from P4 import P4, P4Exception
 
def match(pattern, s):
    c = sre_compile.compile(pattern)
    return c.match(s)
 
p4 = P4()
exit_code = 1
 
try:
    p4.user = 'user'
    p4.password = 'password'
    p4.port = "localhost:1666"
    p4.connect
 
    # desc...
    # {
    #     'status': 'pending',
    #     ...
    #     'depotFile':
    #     [
    #         '//depot/src/file.c'
    #     ],
    #     'change': '12345',
    #     'desc': 'blar blar...'
    # }
    desc = p4.run('describe', sys.argv[1])
    userdesc = desc[0]['desc'].strip()
 
    if match("^<.+> .+$", userdesc):
        exit_code = 0
    else
        print ("changelist description must have the format '<username> desc' ")
 
except P4Exception:
    for e in p4.errors:
        print e
 
sys.exit(exit_code)

2. 파일 내용 검사

서브밋할려고 하는 파일이 C++ 소스 파일일 경우, 스타일 규칙에 부합하는가를 CppStyleChecker를 이용해 검사한다.

import os
import subprocess
import sys
import tempfile
from P4 import P4, P4Exception
 
p4 = P4()
exit_code = 0
 
try:
    p4.user = 'user'
    p4.password = 'password'
    p4.port = "localhost:1666"
    p4.connect
 
    # desc...
    # {
    #     'status': 'pending',
    #     ...
    #     'depotFile':
    #     [
    #         '//depot/src/file.c'
    #     ],
    #     'change': '12345',
    #     'desc': 'blar blar...'
    # }
    desc = p4.run('describe', sys.argv[1])
    filelist = desc[0]['depotFile']
    changeno = desc[0]['change']
 
    # for all file in changelist
    for file in filelist:
        name, ext = os.path.splitext(file)
        ext = ext.lower()
 
        # only handles cpp header/source
        if ext == ".h" or ext == ".cpp":
            # make temp dir & filename
            temp_dir = tempfile.mkdtemp()
            temp_file = os.path.join(temp_dir, os.path.basename(name)) + ext
            may_proceed = True
            f = None
 
            # make temp source file
            try:
                f = open(temp_file, 'w')
                # p4 print -q //depot/src/file.c@=12345
                for i, v, in enumerate(p4.run("print", "-q", "{0}@={1}".format(file, changeno))):
                    if i != 0:
                        f.write(v)
                f.close()
            except:
                if f != None:
                    f.close()
 
                may_proceed = False
 
            if may_proceed:
                # check style
                try:
                    subprocess.check_output(["somewhere\\python.exe", "somewhere\\nsiqcppstyle_exe.py", temp_file])
                except subprocess.CalledProcessError as e:
                    # make submit to fail
                    exit_code = 1
 
                    # print error
                    output = e.output
                    output = output.replace("\r\n", "\n")
                    output = output.replace(temp_file, file)
                    print "\n\ncpp style check failed : ", file
                    print output
 
            # remove temp file
            if os.path.exists(temp_file):
                os.unlink(temp_file)
 
            # remove temp dir
            if os.path.exists(temp_dir):
                os.rmdir(temp_dir)
 
except P4Exception:
    for e in p4.errors:
        print e
 
sys.exit(exit_code)

링크

kb/perforcetrigger.txt · 마지막으로 수정됨: 2014/11/11 14:54 저자 excel96