#!/usr/bin/env ruby begin require 'lolcommits' rescue LoadError require 'rubygems' require 'lolcommits' end require 'optparse' require 'methadone' require 'lolcommits/cli.rb' # allow logging from everywhere include Methadone::CLILogging class App include Methadone::Main include Lolcommits include Lolcommits::CLI description 'git-based selfies for software developers (https://lolcommits.github.io)' version Lolcommits::VERSION main do # check for fatal conditions before execution Fatals.die_if_no_valid_ffmpeg_installed! if capture_animated? Fatals.die_on_fatal_platform_conditions! if options.empty? puts no_options_help else if debug_enabled? logger.level = Logger::DEBUG debug 'Outputting at DEBUG verbosity' end plugin_manager = PluginManager.init config = Configuration.new(plugin_manager, test_mode: options[:test]) if options[:'show-config'] puts config elsif options[:plugins] config.list_plugins elsif options[:devices] puts Platform.device_list puts device_list_help elsif options[:enable] Installation.do_enable(options) elsif options[:disable] Installation.do_disable else # all other commands require a vcs repo, check its present and walk up # to the root dir unless options[:test] Fatals.die_if_not_vcs_repo! change_dir_to_root_or_repo! end if options[:last] show_last_lolimage(config.loldir) elsif options[:browse] Launcher.open_folder(config.loldir) elsif options[:timelapse] TimelapseGif.new(config).run(options[:period]) elsif options[:config] config.do_configure!(options[:plugin]) elsif options[:capture] capture_lolcommit(config) end end end end on('--test', 'run in test mode') on('--debug', 'show debugging info') on('--show-config', 'show config file') on('--devices', 'list available capture devices (mac only)') on('--plugins', 'list all available plugins') on('--config', 'configure a plugin') on('-p', '--plugin {name}', 'plugin name to use with --config') on('-c', '--capture', 'capture lolcommit based on last git commit') on('-e', '--enable', 'install lolcommits for this repo') on('-d', '--disable', 'uninstall lolcommits for this repo') on('-l', '--last', 'view the most recent lolcommit') on('-b', '--browse', 'browse this repo\'s lolcommits') on('--timelapse', 'generate animated timelapse gif from captured images') on('--period {today}', 'period to use for the timelapse gif (today or all)') # optional capturing options on('--device {name}', 'device name to capture from (mac/linux only)') on('-a', '--animate {seconds}', 'enable animated gif captures with duration') on('-w', '--delay {seconds}', 'delay before taking a snapshot') on('--stealth', 'capture image in stealth mode (no output)') on('--fork', 'fork capturing process to the background') on('-s', '--sha {string}', 'pass commit sha manually (--test mode only)') on('-m', '--msg {string}', 'pass commit message manually (--test mode only)') # # No options specified, help the user out # def self.no_options_help # TODO: make this a contextual helper to know whether lolcommits is enabled "Do what exactly?\n" \ "Try: lolcommits --enable (when in a git repository)\n" \ 'Or: lolcommits --help' end def self.debug_enabled? options[:debug] || ENV['LOLCOMMITS_DEBUG'] || false end def self.device_list_help 'Specify a device with --device "{device name}" or set the LOLCOMMITS_DEVICE env variable' end def self.show_last_lolimage(loldir) lolimage = Dir.glob(File.join(loldir, '*.{jpg,gif}')).max_by { |f| File.mtime(f) } if lolimage.nil? warn 'No lolcommits have been captured for this repository yet.' exit 1 end Launcher.open_image(lolimage) end def self.capture_device result = options[:device] || ENV['LOLCOMMITS_DEVICE'] || nil result ||= Dir.glob('/dev/video*').first if Platform.platform_linux? result end def self.capture_lolcommit(config) should_we_fork = options[:fork] || ENV['LOLCOMMITS_FORK'] || false capture_stealth = options[:stealth] || ENV['LOLCOMMITS_STEALTH'] || false capture_delay = (options[:delay] || ENV['LOLCOMMITS_DELAY']).to_i capture_options = { capture_delay: capture_delay, capture_stealth: capture_stealth, capture_device: capture_device, capture_animate: capture_animate, config: config } process_runner = ProcessRunner.new(config) process_runner.fork_me?(should_we_fork) do if options[:test] info '*** Capturing in test mode.' capture_options.merge!(test_capture_options) end runner = Lolcommits::Runner.new(capture_options) runner.run # automatically open the image in test mode Launcher.open_image(runner.main_image) if options[:test] end end def self.test_capture_options { message: options[:msg] || 'this is a test message i didnt really commit something', sha: options[:sha] || "test-#{rand(10**10)}" } end # Duration for animated capturing # # If animation is enabled, returns an integer > 0 representing seconds. # Seconds will be 0 if no option set, or if the platform doesn't support # animated captures (in which case animated capturing will be disabled). # # @return [Integer] def self.capture_animate if Platform.can_animate? (options[:animate] || ENV['LOLCOMMITS_ANIMATE']).to_i else 0 end end def self.capture_animated? capture_animate > 0 end # # change working dir to either a repo or the fs root # def self.change_dir_to_root_or_repo! debug 'Walking up dir tree' loop do cur = File.expand_path('.') nxt = File.expand_path('..', cur) if nxt == cur warn 'Repository root not found' return end return if VCSInfo.repo_root? Dir.chdir(nxt) end end go! end