64
62
return branch_name, branch_url, revision, optional
67
def load_cache(cache_filename):
69
cache_file = open(cache_filename, 'rb')
71
if e.errno == errno.ENOENT:
76
return json.load(cache_file)
79
65
def interpret_config(config_entries, public_only):
80
66
"""Interpret a configuration stream, as parsed by 'parse_config_file'.
192
178
possible_transports=possible_transports)
195
def find_stale(updated, cache, sourcecode_directory, quiet):
196
"""Find branches whose revision info doesn't match the cache."""
197
new_updated = dict(updated)
198
for project, (branch_url, revision, optional) in updated.iteritems():
199
cache_revision_info = cache.get(project)
200
if cache_revision_info is None:
202
if cache_revision_info[0] != int(revision):
204
destination = os.path.join(sourcecode_directory, project)
206
branch = Branch.open(destination)
209
if list(branch.last_revision_info()) != cache_revision_info:
212
print '%s is already up to date.' % project
213
del new_updated[project]
217
def update_cache(cache, cache_filename, changed, sourcecode_directory, quiet):
218
"""Update the cache with the changed branches."""
219
old_cache = dict(cache)
220
for project, (branch_url, revision, optional) in changed.iteritems():
221
destination = os.path.join(sourcecode_directory, project)
222
branch = Branch.open(destination)
223
cache[project] = list(branch.last_revision_info())
224
if cache == old_cache:
226
with open(cache_filename, 'wb') as cache_file:
227
json.dump(cache, cache_file, indent=4)
229
print 'Cache updated. Please commit "%s".' % cache_filename
232
181
def update_branches(sourcecode_directory, update_branches,
233
182
possible_transports=None, tip=False, quiet=False):
234
183
"""Update the existing branches in sourcecode."""
261
210
remote_branch, stop_revision=revision_id, overwrite=True,
262
211
possible_transports=possible_transports)
263
212
except IncompatibleRepositories:
264
# XXX JRV 20100407: Ideally remote_branch.bzrdir._format
213
# XXX JRV 20100407: Ideally remote_branch.bzrdir._format
265
214
# should be passed into upgrade() to ensure the format is the same
266
# locally and remotely. Unfortunately smart server branches
267
# have their _format set to RemoteFormat rather than an actual
215
# locally and remotely. Unfortunately smart server branches
216
# have their _format set to RemoteFormat rather than an actual
268
217
# format instance.
269
218
upgrade(destination)
270
219
# Upgraded, repoen working tree
297
246
os.unlink(destination)
300
def update_sourcecode(sourcecode_directory, config_filename, cache_filename,
301
public_only, tip, dry_run, quiet=False):
249
def update_sourcecode(sourcecode_directory, config_filename, public_only,
250
tip, dry_run, quiet=False):
302
251
"""Update the sourcecode."""
303
252
config_file = open(config_filename)
304
253
config = interpret_config(parse_config_file(config_file), public_only)
305
254
config_file.close()
306
cache = load_cache(cache_filename)
307
255
branches = find_branches(sourcecode_directory)
308
256
new, updated, removed = plan_update(branches, config)
309
257
possible_transports = []
316
264
sourcecode_directory, new, possible_transports, tip, quiet)
317
updated = find_stale(updated, cache, sourcecode_directory, quiet)
319
266
sourcecode_directory, updated, possible_transports, tip, quiet)
320
changed = dict(updated)
323
cache, cache_filename, changed, sourcecode_directory, quiet)
324
267
remove_branches(sourcecode_directory, removed, quiet)
359
302
config_filename = args[2]
361
304
config_filename = os.path.join(root, 'utilities', 'sourcedeps.conf')
362
cache_filename = os.path.join(
363
root, 'utilities', 'sourcedeps.cache')
364
305
if len(args) > 3:
365
306
parser.error("Too many arguments.")
366
307
if not options.quiet:
372
313
sys.stdin, sys.stdout, sys.stderr)
374
315
update_sourcecode(
375
sourcecode_directory, config_filename, cache_filename,
316
sourcecode_directory, config_filename,
376
317
options.public_only, options.tip, options.dry_run, options.quiet)