312 '''Returns true if path matches [keyword] pattern |
312 '''Returns true if path matches [keyword] pattern |
313 and is not a symbolic link. |
313 and is not a symbolic link. |
314 Caveat: localrepository._link fails on Windows.''' |
314 Caveat: localrepository._link fails on Windows.''' |
315 return self.matcher(path) and not islink(path) |
315 return self.matcher(path) and not islink(path) |
316 |
316 |
317 def overwrite(self, node, expand, files): |
317 def overwrite(self, node, expand, candidates): |
318 '''Overwrites selected files expanding/shrinking keywords.''' |
318 '''Overwrites selected files expanding/shrinking keywords.''' |
319 # repo[changeid] introduced in f6c00b17387c |
319 # repo[changeid] introduced in f6c00b17387c |
320 if node is not None: # commit |
320 if node is not None: # commit |
321 try: |
321 try: |
322 ctx = self.repo[node] |
322 ctx = self.repo[node] |
323 except TypeError: |
323 except TypeError: |
324 ctx = self.repo.changectx(node) |
324 ctx = self.repo.changectx(node) |
325 mf = ctx.manifest() |
325 mf = ctx.manifest() |
326 files = [f for f in ctx.files() if f in mf] |
326 candidates = [f for f in ctx.files() if f in mf] |
327 notify = self.ui.debug |
|
328 else: # kwexpand/kwshrink |
327 else: # kwexpand/kwshrink |
329 try: |
328 try: |
330 ctx = self.repo['.'] |
329 ctx = self.repo['.'] |
331 except TypeError: |
330 except TypeError: |
332 ctx = self.repo.changectx() |
331 ctx = self.repo.changectx() |
333 mf = ctx.manifest() |
332 mf = ctx.manifest() |
334 notify = self.ui.note |
|
335 if hasattr(ctx, 'flags'): |
333 if hasattr(ctx, 'flags'): |
336 # 51b0e799352f |
334 # 51b0e799352f |
337 islink = lambda p: 'l' in ctx.flags(p) |
335 islink = lambda p: 'l' in ctx.flags(p) |
338 else: |
336 else: |
339 islink = mf.linkf |
337 islink = mf.linkf |
340 candidates = [f for f in files if self.iskwfile(f, islink)] |
338 candidates = [f for f in candidates if self.iskwfile(f, islink)] |
341 if candidates: |
339 if candidates: |
342 self.restrict = True # do not expand when reading |
340 self.restrict = True # do not expand when reading |
343 candidates.sort() |
341 msg = (expand and _('overwriting %s expanding keywords\n') |
344 action = expand and 'expanding' or 'shrinking' |
342 or _('overwriting %s shrinking keywords\n')) |
345 overwritten = [] |
343 overwritten = [] |
346 for f in candidates: |
344 for f in candidates: |
347 fp = self.repo.file(f) |
345 fp = self.repo.file(f) |
348 data = fp.read(mf[f]) |
346 data = fp.read(mf[f]) |
349 if not textsafe(data): |
347 if not textsafe(data): |
353 data, found = self.substitute(data, f, changenode, |
351 data, found = self.substitute(data, f, changenode, |
354 self.re_kw.subn) |
352 self.re_kw.subn) |
355 else: |
353 else: |
356 found = self.re_kw.search(data) |
354 found = self.re_kw.search(data) |
357 if found: |
355 if found: |
358 notify(_('overwriting %s %s keywords\n') % (f, action)) |
356 self.ui.note(msg % f) |
359 self.repo.wwrite(f, data, mf.flags(f)) |
357 self.repo.wwrite(f, data, mf.flags(f)) |
360 overwritten.append(f) |
358 overwritten.append(f) |
361 _normal(self.repo, overwritten) |
359 _normal(self.repo, overwritten) |
362 self.restrict = False |
360 self.restrict = False |
363 |
361 |
453 '''print [keywordmaps] configuration and an expansion example |
451 '''print [keywordmaps] configuration and an expansion example |
454 |
452 |
455 Show current, custom, or default keyword template maps and their |
453 Show current, custom, or default keyword template maps and their |
456 expansions. |
454 expansions. |
457 |
455 |
458 Extend current configuration by specifying maps as arguments and |
456 Extend the current configuration by specifying maps as arguments |
459 optionally by reading from an additional hgrc file. |
457 and using -f/--rcfile to source an external hgrc file. |
460 |
458 |
461 Override current keyword template maps with "default" option. |
459 Use -d/--default to disable current configuration. |
462 ''' |
460 ''' |
463 def demoitems(section, items): |
461 def demoitems(section, items): |
464 items.sort() |
462 items.sort() |
465 ui.write('[%s]\n' % section) |
463 ui.write('[%s]\n' % section) |
466 for k, v in items: |
464 for k, v in items: |
467 ui.write('%s = %s\n' % (k, v)) |
465 ui.write('%s = %s\n' % (k, v)) |
468 |
466 |
469 msg = 'hg keyword config and expansion example' |
|
470 kwstatus = 'current' |
467 kwstatus = 'current' |
471 fn = 'demo.txt' |
468 fn = 'demo.txt' |
472 branchname = 'demobranch' |
|
473 tmpdir = tempfile.mkdtemp('', 'kwdemo.') |
469 tmpdir = tempfile.mkdtemp('', 'kwdemo.') |
474 ui.note(_('creating temporary repository at %s\n') % tmpdir) |
470 ui.note(_('creating temporary repository at %s\n') % tmpdir) |
475 repo = localrepo.localrepository(ui, tmpdir, True) |
471 repo = localrepo.localrepository(ui, tmpdir, True) |
476 ui.setconfig('keyword', fn, '') |
472 ui.setconfig('keyword', fn, '') |
|
473 |
|
474 uikwmaps = ui.configitems('keywordmaps') |
477 if args or opts.get('rcfile'): |
475 if args or opts.get('rcfile'): |
478 kwstatus = 'custom' |
476 ui.status(_('\n\tconfiguration using custom keyword template maps\n')) |
479 if opts.get('rcfile'): |
477 if uikwmaps: |
480 ui.readconfig(opts.get('rcfile')) |
478 ui.status(_('\textending current template maps\n')) |
481 if opts.get('default'): |
479 if opts.get('default') or not uikwmaps: |
482 kwstatus = 'default' |
480 ui.status(_('\toverriding default template maps\n')) |
|
481 if opts.get('rcfile'): |
|
482 ui.readconfig(opts.get('rcfile')) |
|
483 if args: |
|
484 # simulate hgrc parsing |
|
485 rcmaps = ['[keywordmaps]\n'] + [a + '\n' for a in args] |
|
486 fp = repo.opener('hgrc', 'w') |
|
487 fp.writelines(rcmaps) |
|
488 fp.close() |
|
489 ui.readconfig(repo.join('hgrc')) |
|
490 kwmaps = dict(ui.configitems('keywordmaps')) |
|
491 elif opts.get('default'): |
|
492 ui.status(_('\n\tconfiguration using default keyword template maps\n')) |
483 kwmaps = kwtemplater.templates |
493 kwmaps = kwtemplater.templates |
484 if ui.configitems('keywordmaps'): |
494 if uikwmaps: |
485 # override maps from optional rcfile |
495 ui.status(_('\tdisabling current template maps\n')) |
486 for k, v in kwmaps.iteritems(): |
496 for k, v in kwmaps.iteritems(): |
487 ui.setconfig('keywordmaps', k, v) |
497 ui.setconfig('keywordmaps', k, v) |
488 elif args: |
498 else: |
489 # simulate hgrc parsing |
499 ui.status(_('\n\tconfiguration using current keyword template maps\n')) |
490 rcmaps = ['[keywordmaps]\n'] + [a + '\n' for a in args] |
500 kwmaps = dict(uikwmaps) or kwtemplater.templates |
491 fp = repo.opener('hgrc', 'w') |
501 |
492 fp.writelines(rcmaps) |
|
493 fp.close() |
|
494 ui.readconfig(repo.join('hgrc')) |
|
495 if not opts.get('default'): |
|
496 kwmaps = dict(ui.configitems('keywordmaps')) or kwtemplater.templates |
|
497 reposetup(ui, repo) |
502 reposetup(ui, repo) |
498 for k, v in ui.configitems('extensions'): |
503 for k, v in ui.configitems('extensions'): |
499 if k.endswith('keyword'): |
504 if k.endswith('keyword'): |
500 extension = '%s = %s' % (k, v) |
505 extension = '%s = %s' % (k, v) |
501 break |
506 break |
506 kwkeys = kwmaps.keys() |
511 kwkeys = kwmaps.keys() |
507 kwkeys.sort() |
512 kwkeys.sort() |
508 keywords = '$' + '$\n$'.join(kwkeys) + '$\n' |
513 keywords = '$' + '$\n$'.join(kwkeys) + '$\n' |
509 repo.wopener(fn, 'w').write(keywords) |
514 repo.wopener(fn, 'w').write(keywords) |
510 repo.add([fn]) |
515 repo.add([fn]) |
511 path = repo.wjoin(fn) |
516 ui.note(_('\nkeywords written to %s:\n') % fn) |
512 ui.note(_('\n%s keywords written to %s:\n') % (kwstatus, path)) |
|
513 ui.note(keywords) |
517 ui.note(keywords) |
514 ui.note('\nhg -R "%s" branch "%s"\n' % (tmpdir, branchname)) |
518 try: |
515 # silence branch command if not verbose |
519 repo.dirstate.setbranch('demobranch') |
516 quiet = ui.quiet |
520 except AttributeError: |
517 ui.quiet = not ui.verbose |
521 # before 7e1c8a565a4f |
518 commands.branch(ui, repo, branchname) |
522 repo.opener('branch', 'w').write('demobranch\n') |
519 ui.quiet = quiet |
|
520 for name, cmd in ui.configitems('hooks'): |
523 for name, cmd in ui.configitems('hooks'): |
521 if name.split('.', 1)[0].find('commit') > -1: |
524 if name.split('.', 1)[0].find('commit') > -1: |
522 repo.ui.setconfig('hooks', name, '') |
525 repo.ui.setconfig('hooks', name, '') |
523 ui.note(_('unhooked all commit hooks\n')) |
526 msg = _('hg keyword configuration and expansion example') |
524 ui.note('hg -R "%s" ci -m "%s"\n' % (tmpdir, msg)) |
527 ui.note("hg ci -m '%s'\n" % msg) |
525 repo.commit(text=msg) |
528 repo.commit(text=msg) |
526 fmt = ui.verbose and ' in %s' % path or '' |
529 ui.status(_('\n\tkeywords expanded\n')) |
527 ui.status(_('\n\t%s keywords expanded%s\n') % (kwstatus, fmt)) |
|
528 ui.write(repo.wread(fn)) |
530 ui.write(repo.wread(fn)) |
529 ui.debug('\nremoving temporary repository %s\n' % tmpdir) |
|
530 shutil.rmtree(tmpdir, ignore_errors=True) |
531 shutil.rmtree(tmpdir, ignore_errors=True) |
531 |
532 |
532 def expand(ui, repo, *pats, **opts): |
533 def expand(ui, repo, *pats, **opts): |
533 '''expand keywords in the working directory |
534 '''expand keywords in the working directory |
534 |
535 |