bin/git-ctags

Fri, 09 Dec 2016 15:20:22 -0800

author
Meredith Howard <mhoward@roomag.org>
date
Fri, 09 Dec 2016 15:20:22 -0800
changeset 441
650cbc95b9b0
parent 440
aacbd4032a4c
child 443
e731ef81637c
permissions
-rwxr-xr-x

doc it

#!/usr/bin/env ruby
exit if ENV['CTAGS_SKIP']
ARGV.each { |o| exec('perldoc', $0) if o.match('help') }

ctags  = 'ctags'

dir    = `git rev-parse --show-toplevel`.chomp

conf   = "#{dir}/.git/ctags.conf"
target = "#{dir}/.tags"
tmp    = "#{dir}/.tags.#{$$}~"

opts   = File.exists?(conf) ? "--options=#{conf}" : ''

sleep 5 if ENV['CTAGS_HOOK']

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
    git ls-files \
     | #{ctags} --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 w/o env, immediately run ctags and replace tags file.

When run with C<CTAGS_HOOK>, it's assumed to be a BG process and we want to
wait for git to be done applying changes no matter how the hook is triggered.
Wait five seconds, then bail if we can't get a lock on the tags file or if it's
been updated within the last minute. Only then, run ctags and replace the tags
file.

=cut

mercurial