2017-05-06 12 views
0

リポジトリを複数のディレクトリにエクスポートするためのsvnのポスト・コミット・フック・スクリプトを作成しようとしています(コードをコミットするときに、他のディレクトリにも)。たとえば、私は4つのパス(またはディレクトリ)A、B、C、Dを持つレポを持っています。もし私がAでコミットすれば、リビジョンはB、C、Dにも行かなければならない。同様に私がBでコミットした場合、リビジョンはC、Dに移動し、CでコミットするとDに反映する必要があります。Subversion post-commitフックを他のディレクトリにエクスポートするようにしました

私はコミット後について知りましたが、使用方法はわかりません。私は部分的に動作しているこのコードを書いています。すなわち私が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) 

での作業今では期待通りに必要な仕事をしました!

関連する問題