hgkw/keyword.py
branch0.9.2compat
changeset 704 772628d1ccb5
parent 698 0b77aa7ff437
child 984 a4ea5c2d3ff3
equal deleted inserted replaced
698:0b77aa7ff437 704:772628d1ccb5
   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 
   550     expansion.
   551     expansion.
   551 
   552 
   552     See "hg help keyword" on how to construct patterns both for
   553     See "hg help keyword" on how to construct patterns both for
   553     inclusion and exclusion of files.
   554     inclusion and exclusion of files.
   554 
   555 
   555     Use -u/--untracked to list untracked files as well.
       
   556 
       
   557     With -A/--all and -v/--verbose the codes used to show the status
   556     With -A/--all and -v/--verbose the codes used to show the status
   558     of files are:
   557     of files are:
       
   558 
   559       K = keyword expansion candidate
   559       K = keyword expansion candidate
   560       k = keyword expansion candidate (not tracked)
   560       k = keyword expansion candidate (not tracked)
   561       I = ignored
   561       I = ignored
   562       i = ignored (not tracked)
   562       i = ignored (not tracked)
   563     '''
   563     '''