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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# only tested with cpython!
import optparse, os, shutil, sys
from os import path
from testlib import filters
__doc__ = """
Creates and maintains a 'clone' of the test suite, optionally transforming
the source code through a filter. The primary purpose of this utility is
to allow the tests to run on Python VMs that do not implement a parser that
groks 2.4 style @decorations.
Creating a clone:
Create a new, exact clone of the suite:
$ python test/clone.py -c myclone
Create a new clone using the 2.3 filter:
$ python test/clone.py -c --filter=py23 myclone
After the clone is set up, changes in the master can be pulled into the clone
with the -u or --update switch. If the clone was created with a filter, it
will be applied automatically when updating.
Update the clone:
$ python test/clone.py -u myclone
The updating algorithm is very simple: if the version in test/ is newer than
the one in your clone, the clone version is overwritten.
"""
options = None
clone, clone_path = None, None
filter = lambda x: x[:]
def optparser():
parser = optparse.OptionParser(
usage=('usage: %prog [options] CLONE-NAME\n' + __doc__ ).rstrip())
parser.add_option('-n', '--dry-run', dest='dryrun',
action='store_true',
help=('Do not actually change any files; '
'just print what would happen.'))
parser.add_option('-u', '--update', dest='update', action='store_true',
help='Update an existing clone.')
parser.add_option('-c', '--create', dest='create', action='store_true',
help='Create a new clone.')
parser.add_option('--filter', dest='filter',
help='Run source code through a filter.')
parser.add_option('-l', '--filter-list', dest='filter_list',
action='store_true',
help='Show available filters.')
parser.add_option('-f', '--force', dest='force', action='store_true',
help='Overwrite clone files even if unchanged.')
parser.add_option('-q', '--quiet', dest='quiet', action='store_true',
help='Run quietly.')
parser.set_defaults(update=False, create=False,
dryrun=False, filter_list=False,
force=False, quiet=False)
return parser
def config():
global clone, clone_path, options, filter
parser = optparser()
(options, args) = parser.parse_args()
if options.filter_list:
if options.quiet:
print '\n'.join(filters.__all__)
else:
print 'Available filters:'
for name in filters.__all__:
print '\t%s' % name
sys.exit(0)
if not options.update and not options.create:
parser.error('One of -u or -c is required.')
if len(args) != 1:
parser.error('A clone name is required.')
clone = args[0]
clone_path = path.abspath(clone)
if options.update and not path.exists(clone_path):
parser.error(
'Clone %s does not exist; create it with --create first.' % clone)
if options.create and path.exists(clone_path):
parser.error('Clone %s already exists.' % clone)
if options.filter:
if options.filter not in filters.__all__:
parser.error(('Filter "%s" unknown; use --filter-list to see '
'available filters.') % options.filter)
filter = getattr(filters, options.filter)
def setup():
global filter
if options.create:
if not options.quiet:
print "mkdir %s" % clone_path
if not options.dryrun:
os.mkdir(clone_path)
if options.filter and not options.dryrun:
if not options.quiet:
print 'storing filter "%s" in %s/.filter' % (
options.filter, clone)
stash = open(path.join(clone_path, '.filter'), 'w')
stash.write(options.filter)
stash.close()
else:
stash_file = path.join(clone_path, '.filter')
if path.exists(stash_file):
stash = open(stash_file)
stashed = stash.read().strip()
stash.close()
if options.filter:
if (options.filter != stashed and stashed in filters.__all__ and
not options.quiet):
print (('Warning: --filter=%s overrides %s specified in '
'%s/.filter') % (options.filter, stashed, clone))
else:
if stashed not in filters.__all__:
sys.stderr.write(
'Filter "%s" in %s/.filter is not valid, aborting.' %
(stashed, clone))
sys.exit(-1)
filter = getattr(filters, stashed)
def sync():
source_path, _ = path.split(path.abspath(__file__))
ls = lambda root: [fn
for fn in os.listdir(root)
if (fn.endswith('.py') and not fn.startswith('.'))]
def walker(x, dirname, fnames):
if '.svn' in fnames:
fnames.remove('.svn')
rel_path = dirname[len(source_path) + 1:]
dest_path = path.join(clone_path, rel_path)
if not path.exists(dest_path):
if not options.quiet:
print "mkdir %s/%s" % (clone, rel_path)
if not options.dryrun:
os.mkdir(dest_path)
for filename in ls(dirname):
source_file = path.join(source_path, rel_path, filename)
dest_file = path.join(dest_path, filename)
if (options.force or
(not path.exists(dest_file) or
os.stat(source_file)[-1] > os.stat(dest_file)[-1])):
if not options.quiet:
print "syncing %s" % path.join(rel_path, filename)
raw = open(source_file)
filtered = filter(raw.readlines())
raw.close()
if not options.dryrun:
synced = open(dest_file, 'w')
synced.writelines(filtered)
synced.close()
os.path.walk(source_path, walker, None)
if __name__ == '__main__':
config()
setup()
sync()
|