Fri, 09 Dec 2016 15:09:08 -0800
Fixup git-ctags
#!/usr/bin/env ruby # Meant for use as a git hook: # 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 = '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