Last active
December 19, 2015 11:19
-
-
Save keitaoouchi/5946604 to your computer and use it in GitHub Desktop.
git-svnでリビジョン番号かチケット番号でデプロイファイルの一覧を出力する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""git-svnでリビジョン番号かチケット番号でデプロイファイルの一覧を出力する | |
python gitsvn.py -d /path/to/repos -r 1 2 3 | |
python gitsvn.py -d /path/to/repos -t 1000 | |
""" | |
import re | |
import os | |
import subprocess | |
import argparse | |
PIPE = subprocess.PIPE | |
def listup_revisions(ticket): | |
pattern = re.compile("r(\d+) .+ #{} .+".format(ticket)) | |
git = which_git() | |
process = subprocess.Popen([git, "svn", "log", "--oneline"], stdout=PIPE, stderr=PIPE) | |
out = process.communicate()[0] | |
lines = out.splitlines() | |
revisions = [] | |
for line in lines: | |
matcher = pattern.match(str(line, encoding="utf-8")) | |
if matcher: | |
revision, = matcher.groups() | |
revisions.append(revision) | |
return sorted(set(revisions)) | |
def which_git(): | |
process = subprocess.Popen(["which", "git"], stdout=PIPE, stderr=PIPE) | |
out = process.communicate()[0] | |
return str(out.strip(b"\n"), encoding="utf-8") | |
def svn_log(revision): | |
git = which_git() | |
process = subprocess.Popen([git, "svn", "log", "-r", revision, "-v"], stdout=PIPE, stderr=PIPE) | |
return process.communicate()[0] | |
def analize_log(log_message): | |
result = {'A': set(), 'M': set(), 'D': set()} | |
parser = re.compile("\s+(A|M|D)\s(.+)$") | |
lines = log_message.splitlines(False) | |
for line in lines: | |
matcher = parser.match(str(line, encoding="utf-8")) | |
if matcher: | |
edit_type, path = matcher.groups() | |
result[edit_type].add(path) | |
return result | |
def aggregate(list_of_log_maps): | |
result = {'A': set(), 'M': set(), 'D': set()} | |
for log_map in list_of_log_maps: | |
deleted_files = log_map['D'] | |
for deleted_file in deleted_files: | |
if deleted_file in result['A']: | |
result['A'].remove(deleted_file) | |
elif deleted_file in result['M']: | |
result['M'].remove(deleted_file) | |
else: | |
result['D'].add(deleted_file) | |
modified_files = log_map['M'] | |
for modified_file in modified_files: | |
if modified_file in result['A']: | |
result['A'].remove(modified_file) | |
result['M'].add(modified_file) | |
append_files = log_map['A'] | |
result['A'].update(append_files) | |
return result | |
def main(root, ticket, revisions=None): | |
os.chdir(root) | |
revisions = revisions if revisions else listup_revisions(ticket) | |
print("--------target revisions--------") | |
print(revisions) | |
log_maps = [] | |
for revision in revisions: | |
r = str(revision) if isinstance(revision, int) else revision | |
log = svn_log(r) | |
log_map = analize_log(log) | |
log_maps.append(log_map) | |
result = aggregate(log_maps) | |
upload_target = set() | |
delete_target = set() | |
upload_target.update(result['A']) | |
upload_target.update(result['M']) | |
delete_target.update(result['D']) | |
return upload_target, delete_target | |
def parse_args(): | |
parser = argparse.ArgumentParser(description='Parse arguments') | |
parser.add_argument('-d', '--dir', action="store", required=True, | |
help='path to repository root directory') | |
parser.add_argument('-r', '--revisions', action="append", | |
type=int, nargs='+', help='revision strings') | |
parser.add_argument('-t', '--ticket', action="store", | |
nargs='?', type=int, help='ticket number') | |
args = parser.parse_args() | |
return args.dir, args.revisions[0] if args.revisions else [], args.ticket | |
if __name__ == '__main__': | |
root, revisions, ticket = parse_args() | |
u, d = main(root, ticket, revisions) | |
up = sorted(u) | |
de = sorted(d) | |
print("------Upload------") | |
for f in up: | |
print(f) | |
print("") | |
print("------Delete------") | |
for f in de: | |
print(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment