Sat, 10 Dec 2016 16:42:04 -0500
support hg in git-ctags, deduplicate hg helper stuff
#!/usr/bin/env ruby exit if ENV['CTAGS_SKIP'] ARGV.each { |o| exec('perldoc', $0) if o.match('help') } ctags_bin = ENV['CTAGS_BIN'] || 'ctags' if (dir = `git rev-parse --show-toplevel 2>/dev/null`.chomp) != '' list_cmd = 'git ls-files' conf = "#{dir}/.git/ctags.conf" elsif (dir = `hg root 2>/dev/null`.chomp) != '' list_cmd = 'hg stat -Aqn' conf = "#{dir}/.hg/ctags.conf" else abort 'not an hg or git repository' end target = "#{dir}/.tags" tmp = "#{dir}/.tags.#{$$}~" opts = File.exists?(conf) ? "--options=#{conf}" : '' if ENV['CTAGS_HOOK'] fork and exit sleep 5 end open(target, File::RDONLY|File::CREAT, 0644) do |f| if ENV['CTAGS_HOOK'] exit unless f.flock(File::LOCK_EX|File::LOCK_NB) exit unless (Time.now - f.mtime) > 60 end system(<<-CMD) or exit $?.exitstatus #{list_cmd} \ | #{ctags_bin} --tag-relative -L - -f"#{tmp}" #{opts} \ && mv #{tmp} #{target} CMD end exit 0 <<'=cut' =head1 NAME git-ctags - run ctags on git tracked files =head1 SYNOPSIS git ctags echo 'CTAGS_HOOK=1 git ctags' >> .git/hooks/post-checkout git checkout some/branch CTAGS_SKIP=1 git checkout some/branch =head1 DESCRIPTION Create a .tags file (target) using git's list of tracked files. If C<.git/ctags.conf> exists in the repo it is passed to the ctags invocation. When run with C<CTAGS_HOOK> set, additional behavior is enabled to avoid excess re-runs during multiple VCS operations, and the work is moved to background as well. =head2 Mercurial Mercurial repositories are supported too, with git taking priority when finding a repo root. To add a hook, in the repository C<.hg/hgrc>, add: [hooks] update = CTAGS_HOOK=1 git ctags In a Mercurial repo, additional options can be put in C<.hg/ctags.conf>. =head1 ENVIRONMENT =head2 CTAGS_SKIP If true, exit immediately. =head2 CTAGS_HOOK If true, run as a VCS hook. This causes git-ctags to fork and exit, wait five seconds, then try to lock and update the tags file if it hasn't been updated in the last minute. =head2 CTAGS_BIN If set, use this to invoke ctags rather than assuming C<ctags> can be found in path. =cut