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
|
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
import os,re
entities = [
("<","<"), (">", ">"), (""", '"'), ("'", "'"),
("&", "&")
]
def unescape(data):
for old,new in entities:
data = data.replace(old,new)
return data
patterns = [
(convert_path('CVS/Entries'), re.compile(r"^\w?/([^/]+)/", re.M), None),
(convert_path('.svn/entries'), re.compile(r'name="([^"]+)"'), unescape),
]
def joinpath(prefix,suffix):
if not prefix:
return suffix
return os.path.join(prefix,suffix)
def walk_revctrl(dirname='', memo=None):
"""Find all files under revision control"""
if memo is None:
memo = {}
if dirname in memo:
# Don't rescan a scanned directory
return
for path, pattern, postproc in patterns:
path = joinpath(dirname,path)
if os.path.isfile(path):
f = open(path,'rU')
data = f.read()
f.close()
for match in pattern.finditer(data):
path = match.group(1)
if postproc:
path = postproc(path)
path = joinpath(dirname,path)
if os.path.isfile(path):
yield path
elif os.path.isdir(path):
for item in walk_revctrl(path, memo):
yield item
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
def run(self):
_sdist.run(self)
dist_files = getattr(self.distribution,'dist_files',[])
for file in self.archive_files:
data = ('sdist', '', file)
if data not in dist_files:
dist_files.append(data)
def finalize_options(self):
_sdist.finalize_options(self)
if not os.path.isfile(self.template):
self.force_manifest = 1 # always regen if no template
def add_defaults(self):
_sdist.add_defaults(self)
self.filelist.extend(walk_revctrl())
|