2017-05-06 58 views
0

我想写一个提交钩子脚本svn导出存储库到多个目录(所以当你提交代码,该代码的最新版本被复制到其他目录也)。例如,我有一个具有4个路径(或目录)A,B,C,D的仓库。我想如果我在A中提交,那么修订也应该到B,C,D。同样,如果我在B中提交,那么修订应该转到C,D,并且同样当在C上提交时,它应该反映在D.颠覆后提交钩子触发导出回购到其他目录

我开始了解后提交,但不知道如何使用它。我已经写了这部分工作的一堆代码。即当我在A中提交时,它转到B但不转到C或D,同样,当我在B上提交时,它转到C但不转到D.

我之前没有做过脚本编写。我做了测试回购测试来测试我的工作。

#!/usr/bin/python 

import os 
import re 
import sys 

from subprocess import Popen, PIPE 

REPOS, REV, TXN_NAME = sys.argv[1:] 

SVNADMIN = '/opt/softwares/csvn/bin/svnadmin' 

MAPPINGS = [ 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
] 

TMP_MAPPINGS = MAPPINGS 
MAPPINGS = [] 

for mapping in TMP_MAPPINGS: 
    if mapping not in MAPPINGS: 
     MAPPINGS.append(mapping) 

del TMP_MAPPINGS 
MAPPINGS.sort(key=lambda mapping: len(mapping['FROM']['PATH']), reverse=True) 

def map_(revision_content, to_repos): 
    pattern = '\n(?:Node-path|Node-copyfrom-path): ([^\n]*)\n' 
    mapped = {'VALUE': False} 

    def repl(match): 
     path = match.group(1) 

     for mapping in MAPPINGS: 
      if os.path.samefile(mapping['FROM']['REPOS'], REPOS) \ 
       and mapping['TO']['REPOS'] == to_repos \ 
       and path.startswith(mapping['FROM']['PATH']): 

       path = mapping['TO']['PATH'] + path[len(mapping['FROM']['PATH']):] 
       mapped['VALUE'] = True 
       break 

     return re.sub(': [^\n]*', ': ' + path, match.group(0), 1) 

    return re.sub(pattern, repl, revision_content), mapped['VALUE'] 

there_were_errors = False 
processed_to_repos = [] 
revision_content = None 

for mapping in MAPPINGS: 
    if not os.path.samefile(mapping['FROM']['REPOS'], REPOS): 
     continue 

    to_repos = mapping['TO']['REPOS'] 

    if to_repos in processed_to_repos: 
     continue 
    processed_to_repos.append(to_repos) 

    if revision_content is None: 
     dump_process = Popen([SVNADMIN, 'dump', REPOS, '-r', REV, '--incremental', '-q'], stdout=PIPE, stderr=PIPE) 
     revision_content, errors = dump_process.communicate() 

     if errors: 
      print >> sys.stderr, errors 
      there_were_errors = True 
      break 

    mapped_revision_content, mapped = map_(revision_content, to_repos) 

    if not mapped: 
     continue 

    load_process = Popen([SVNADMIN, 'load', to_repos, '-r', REV, '--ignore-uuid', '-q'], stdin=PIPE, stderr=PIPE) 
    _, errors = load_process.communicate(mapped_revision_content) 

    if errors: 
     print >> sys.stderr, errors 
     there_were_errors = True 

if there_were_errors: 
    sys.exit(1) 
sys.exit(0) 
+0

你做了什么调试?如果您的问题是“请为我调试并修复脚本”,我担心这是Stack Overflow的一个相当广泛的问题。 – halfer

+0

这听起来像是一个更适合持续集成/部署系统的任务。这样,用户不必等待挂钩脚本在每次提交时完成执行。 – alroc

回答

0

OK了吧..有

#!/usr/bin/python 

import os 
import re 
import sys 

from subprocess import Popen, PIPE 

REPOS, REV, TXN_NAME = sys.argv[1:] 

SVNADMIN = '/opt/softwares/csvn/bin/svnadmin' 

MAPPINGS = [ 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'A'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'B'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
    { 
     'FROM': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'C'}, 
     'TO': {'REPOS': '/opt/softwares/csvn/data/repositories/Test', 'PATH': 'D'} 
    }, 
] 

MAPPINGS.sort(key=lambda mapping: len(mapping['FROM']['PATH']), reverse=True) 

def map_(revision_content, to_repos): 
    global MAPPINGS 
    pattern = '\n(?:Node-path|Node-copyfrom-path): ([^\n]*)\n' 
    mapped = {'VALUE': False} 

    def repl(match): 
     global MAPPINGS 
     path = match.group(1) 
     for mapping in MAPPINGS: 
      if os.path.samefile(mapping['FROM']['REPOS'], REPOS) \ 
       and mapping['TO']['REPOS'] == to_repos \ 
       and path.startswith(mapping['FROM']['PATH']): 
       path = mapping['TO']['PATH'] + path[len(mapping['FROM']['PATH']):] 
       mapped['VALUE'] = True 
       break 
     return re.sub(': [^\n]*', ': ' + path, match.group(0), 1) 
    return re.sub(pattern, repl, revision_content), mapped['VALUE'] 

there_were_errors = False 
revision_content = None 

dump_process = Popen([SVNADMIN, 'dump', REPOS, '-r', REV, '--incremental', '-q'], stdout=PIPE, stderr=PIPE) 
revision_content, errors = dump_process.communicate() 
if errors: 
    print >> sys.stderr, errors 
    there_were_errors = True 

for mapping in MAPPINGS: 
    if there_were_errors: 
     break 
    if not os.path.samefile(mapping['FROM']['REPOS'], REPOS): 
     continue 
    to_repos = mapping['TO']['REPOS'] 
    mapped_revision_content, mapped = map_(revision_content, to_repos) 
    if not mapped: 
     continue 
    load_process = Popen([SVNADMIN, 'load', to_repos, '-r', REV, '--ignore-uuid', '-q'], stdin=PIPE, stderr=PIPE) 
    _, errors = load_process.communicate(mapped_revision_content) 
    revision_content = mapped_revision_content 
    if errors: 
     print >> sys.stderr, errors 
     there_were_errors = True 

if there_were_errors: 
    sys.exit(1) 
sys.exit(0) 

现在确实如预期所需要的岗位上工作!