bin/git-ctags

changeset 440
aacbd4032a4c
parent 187
84c6fa7ebc05
child 441
650cbc95b9b0
copy from .git_helpers/ctags
copy to bin/git-ctags
--- a/.git_helpers/ctags
+++ b/bin/git-ctags
@@ -1,34 +1,44 @@
 #!/usr/bin/env ruby
 
 # Meant for use as a git hook:
-#   CTAGS_HOOK=1 .git/hooks/ctags &>/dev/null </dev/null &
+#   CTAGS_HOOK=1 ~/.git_helpers/ctags &>/dev/null </dev/null &
 # or an aliased cmd on demand:
 #   git config alias.ctags '!.git/hooks/ctags'
 # or disable when you wish:
 #   CTAGS_SKIP=1 git rebase
 
+# Create a tags file (target) using git's list of tracked files.  If
+# .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 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.
+
 exit if ENV['CTAGS_SKIP']
 
-ctags  = "/opt/local/bin/ctags"
-ctags  = 'ctags' if !File.exists?(ctags)
+ctags  = 'ctags'
 
 dir    = `git rev-parse --show-toplevel`.chomp
 
 conf   = "#{dir}/.git/ctags.conf"
 target = "#{dir}/.tags"
-tmp    = "#{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|
+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
+    exit unless f.flock(File::LOCK_EX|File::LOCK_NB)
+    exit unless (Time.now - f.mtime) > 60
   end
 
-  system( <<-CMD ) or exit $?.exitstatus
+  system(<<-CMD) or exit $?.exitstatus
     git ls-files \
      | #{ctags} --tag-relative -L - -f"#{tmp}" #{opts} \
     && mv #{tmp} #{target}

mercurial