This repository has been archived by the owner on Aug 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
analyze.py
124 lines (109 loc) · 4.16 KB
/
analyze.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Copyright Dave Abrahams 2013. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
######################################################################
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
######################################################################
import sys
import svn.fs, svn.delta, svn.repos, svn.core
# Available change actions
from svn.repos import CHANGE_ACTION_MODIFY,CHANGE_ACTION_ADD,CHANGE_ACTION_DELETE,CHANGE_ACTION_REPLACE
from svn.core import svn_node_dir, svn_node_file, svn_node_none, svn_node_unknown
import analyzer
repr_map = {
'item_kind' : {
svn_node_dir:'directory',
svn_node_file:'file',
svn_node_none:'None',
svn_node_unknown:'UNKNOWN'
},
'action' : {
CHANGE_ACTION_MODIFY:'modify',
CHANGE_ACTION_ADD:'add',
CHANGE_ACTION_DELETE:'delete',
CHANGE_ACTION_REPLACE:'replace'
}}
class Repository(object):
def __init__(self, path):
self.repo = svn.repos.open(
svn.core.svn_dirent_canonicalize(path))
self.fs = svn.repos.fs(self.repo)
def youngest_rev(self):
return svn.fs.youngest_rev(self.fs)
class Revision(object):
__slots__ = ('modified_tree', 'copied_tree', 'deleted_tree')
def __init__(self, modified_tree, copied_tree, deleted_tree):
self.modified_tree = modified_tree
self.copied_tree = copied_tree
self.deleted_tree = deleted_tree
def get_changeset(repo, revnum):
root = svn.fs.revision_root(repo.fs, revnum)
collector = analyzer.ChangeCollector(repo.fs, root)
editor, baton = svn.delta.make_editor(collector)
svn.repos.replay(root, editor, baton)
return collector.get_changes().items()
def log(*args, **kw):
print '***',
for a in args:
print a,
for k,v in kw.items():
print k, '=', v
class ChangeCollector(object):
def __init__(self, repo, root = ''):
self.collector = analyzer.ChangeCollector(repo.fs, root)
self.editor_ptr, self.e_baton = svn.delta.make_editor(self.collector)
funky_move_revs = range(38327, 38330)
def run():
repo = Repository(sys.argv[1])
max_rev = repo.youngest_rev()
# Preallocate database of revisions
revisions = [None]*(max_rev+1)
branches = {'trunk/boost':[], 'trunk':[]}
for revnum in range(max_rev + 1):
print '='*5, revnum, '='*5
changes = get_changeset(repo, revnum)
print 'rooted at:', (None if len(changes) == 0 else path_lcd(p for p,c in changes))
for p, data in changes:
import pprint
pprint.pprint((
p,
dict(((s,
repr_map.get(s,{}).get(getattr(data,s), getattr(data,s))
) for s in data.__slots__))
))
def path_lcd(paths):
"""
>>> path_lcd(['a/b/c/d/e', 'a/b/c/q/r', 'a/b/c/f/g'])
'a/b/c'
>>> path_lcd(['apple/bear/cat', 'bob/slack'])
''
"""
remaining_paths = iter(paths)
lcd = remaining_paths.next().split('/')
for p in remaining_paths:
elements = p.split('/')
for n in range(min(len(lcd), len(elements))):
if lcd[n] != elements[n]:
lcd = lcd[:n]
break
return intern('/'.join(lcd))
if __name__ == '__main__':
import doctest
doctest.testmod()
run()