#!/usr/bin/env ruby # # git-remote-monitor(1) # # The MIT License # Copyright © 2009 # * Magnus Bergmark # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # Add ../lib/ as a load path in case we are doing development $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) REQUIRED_GEMS = ['rubygems'] begin REQUIRED_GEMS.each { |g| require g } rescue LoadError => e failed_gem = e.to_s.slice(/-- (.*)$/, 1) $stderr.puts "ERROR: Could not load #{failed_gem}." $stderr.puts "#{$0} needs the following gems:" $stderr.puts REQUIRED_GEMS.collect { |g| "\t* #{g}" }.join("\n") Kernel.exit(1) end require 'git_remote_monitor' require 'getoptlong' require 'rdoc/usage' $usage = %Q{ = Synopsis Monitors the HEAD's (current branch) remote for changes at a fixed interval. Changes will be fetched and you will be notified about them in any notification system you specify. = Usage git remote-monitor [OPTIONS] [DIR] When no DIR is specified, current working directory will be used. == Options -h, --help: displays this usage information -V, --version: displays version information -i TIME, --interval=TIME: time, in seconds, between each fetch. Defaults to 60 seconds. -p, --list-plugins: list all notification plugins and show which ones are active on your system, then quit. == Daemon Since this utility is in an early stage, no daemon capabilities have yet been added. It is recommended that you start the command in the background (append a single & to the end of the command line) so you can keep using your term to other things while the program is running. } # # Usage information # # Shamefully stolen from RDoc#usage. We cannot use RDoc::usage because # RubyGems will call this from a wrapper, and #usage is hardcoded to look # at the top-level file instead of the current one. I have changed this # code to instead just parse a string. def usage_information markup = SM::SimpleMarkup.new flow_convertor = SM::ToFlow.new flow = markup.convert($usage, flow_convertor) options = RI::Options.instance formatter = options.formatter.new(options, "") formatter.display_flow(flow) end def version_information require 'yaml' version = YAML::load_file(File.join(GitRemoteMonitor.root, 'VERSION.yml')) stability = (version[:minor] % 2 == 0) ? "stable" : "unstable" puts "#{File.basename($0)} version #{version[:major]}.#{version[:minor]}.#{version[:patch]} (#{stability})" puts "Run in ruby #{RUBY_VERSION} (#{RUBY_PLATFORM}) released #{RUBY_RELEASE_DATE}, patchlevel #{RUBY_PATCHLEVEL}" end def list_plugins loaded = GitRemoteMonitor::Notifiers.notifier_plugins available = GitRemoteMonitor::Notifiers.available_notifiers preferred = GitRemoteMonitor::Notifiers.preferred_notifier puts "Plugins currently in this version of git-remote-monitor:" loaded.each do |plugin| status = if plugin == preferred " (Available, Active)" elsif available.include?(plugin) " (Available)" else "" end plugin_name = plugin.to_s.sub(/^.*::/, '') puts "\t* #{plugin_name}#{status}" end end # # Command line arguments parser # def parse_command_line_arguments! opts = GetoptLong.new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--version', '-V', GetoptLong::NO_ARGUMENT ], [ '--list-plugins', '-p', GetoptLong::NO_ARGUMENT ], [ '--interval', '-i', GetoptLong::REQUIRED_ARGUMENT] ) opts.each do |opt, arg| case opt when '--help' usage_information exit(0) when '--version' version_information exit(0) when '--list-plugins' list_plugins exit(0) when '--interval' interval = arg.to_i unless interval > 10 puts "ERROR: Interval must be larger than 10" exit 1 end $interval = interval end end # ARGV now contains all non-params. Check for only one extra param, max. This is the DIR. if $ARGV.size > 1 $stderr.puts "Only one directory may be specified!" Kernel.exit(1) elsif $ARGV.size == 1 $dir = $ARGV.first end end # Default values for the command line options $interval = 60 $dir = Dir.pwd begin parse_command_line_arguments! notifier = GitRemoteMonitor::Notifier.new monitor = GitRemoteMonitor::Monitor.new($dir, $interval, notifier) monitor.start_monitoring! rescue => e $stderr.puts "-- Unhandled Exception! ------" $stderr.puts e $stderr.puts e.backtrace Kernel.exit(1) end