lolcommits 0.5.7 → 0.5.8.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +16 -161
- data/.travis.yml +11 -4
- data/Gemfile +2 -2
- data/Rakefile +24 -32
- data/bin/lolcommits +62 -125
- data/features/bugs.feature +24 -9
- data/features/lolcommits.feature +136 -145
- data/features/plugins.feature +16 -33
- data/features/step_definitions/lolcommits_steps.rb +91 -71
- data/features/support/env.rb +18 -48
- data/features/support/path_helpers.rb +9 -8
- data/lib/lolcommits.rb +3 -10
- data/lib/lolcommits/capturer.rb +10 -2
- data/lib/lolcommits/capturer/capture_linux.rb +1 -1
- data/lib/lolcommits/capturer/capture_linux_animated.rb +12 -13
- data/lib/lolcommits/capturer/capture_mac_animated.rb +12 -13
- data/lib/lolcommits/cli/fatals.rb +77 -0
- data/lib/lolcommits/cli/launcher.rb +29 -0
- data/lib/lolcommits/cli/process_runner.rb +48 -0
- data/lib/lolcommits/cli/timelapse_gif.rb +45 -0
- data/lib/lolcommits/configuration.rb +30 -133
- data/lib/lolcommits/git_info.rb +58 -28
- data/lib/lolcommits/installation.rb +11 -21
- data/lib/lolcommits/platform.rb +134 -0
- data/lib/lolcommits/plugin.rb +2 -2
- data/lib/lolcommits/plugins/dot_com.rb +15 -15
- data/lib/lolcommits/plugins/lol_protonet.rb +68 -0
- data/lib/lolcommits/plugins/lol_twitter.rb +12 -15
- data/lib/lolcommits/plugins/lol_yammer.rb +4 -6
- data/lib/lolcommits/plugins/lolsrv.rb +8 -11
- data/lib/lolcommits/plugins/loltext.rb +7 -7
- data/lib/lolcommits/plugins/tranzlate.rb +70 -70
- data/lib/lolcommits/plugins/uploldz.rb +8 -8
- data/lib/lolcommits/runner.rb +36 -35
- data/lib/lolcommits/version.rb +1 -1
- data/lolcommits.gemspec +11 -10
- data/test/lolcommits_test.rb +35 -0
- data/test/plugins_test.rb +52 -0
- metadata +41 -20
- data/test/test_lolcommits.rb +0 -78
@@ -12,7 +12,7 @@ module Lolcommits
|
|
12
12
|
tmpdir = Dir.mktmpdir
|
13
13
|
|
14
14
|
# Default delay is 1s
|
15
|
-
delay =
|
15
|
+
delay = capture_delay != 0 ? capture_delay : 1
|
16
16
|
|
17
17
|
# There's no way to give a capture delay in mplayer, but a number of frame
|
18
18
|
# mplayer's "delay" is actually a number of frames at 25 fps
|
@@ -8,21 +8,20 @@ module Lolcommits
|
|
8
8
|
|
9
9
|
# capture the raw video with ffmpeg video4linux2
|
10
10
|
system_call "ffmpeg -v quiet -y -f video4linux2 -video_size 320x240 -i #{capture_device_string} -t #{capture_duration} #{video_location} > /dev/null"
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
return unless File.exist?(video_location)
|
12
|
+
# convert raw video to png frames with ffmpeg
|
13
|
+
system_call "ffmpeg #{capture_delay_string} -v quiet -i #{video_location} -t #{animated_duration} #{frames_location}/%09d.png > /dev/null"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
# use fps to set delay and number of frames to skip (for lower filesized gifs)
|
16
|
+
fps = video_fps(video_location)
|
17
|
+
skip = frame_skip(fps)
|
18
|
+
delay = frame_delay(fps, skip)
|
19
|
+
debug "Capturer: anaimated gif choosing every #{skip} frames with a frame delay of #{delay}"
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
21
|
+
# create the looping animated gif from frames (picks nth frame with seq)
|
22
|
+
seq_command = "seq -f #{frames_location}/%09g.png 1 #{skip} #{Dir["#{frames_location}/*"].length}"
|
23
|
+
# convert to animated gif with delay and gif optimisation
|
24
|
+
system_call "convert -layers OptimizeTransparency -delay #{delay} -loop 0 `#{seq_command}` -coalesce #{snapshot_location} > /dev/null"
|
26
25
|
end
|
27
26
|
|
28
27
|
private
|
@@ -8,21 +8,20 @@ module Lolcommits
|
|
8
8
|
|
9
9
|
# capture the raw video with videosnap
|
10
10
|
system_call "#{executable_path} -s 240 #{capture_device_string}#{capture_delay_string}-t #{animated_duration} --no-audio #{video_location} > /dev/null"
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
return unless File.exist?(video_location)
|
12
|
+
# convert raw video to png frames with ffmpeg
|
13
|
+
system_call "ffmpeg -v quiet -i #{video_location} -t #{animated_duration} #{frames_location}/%09d.png"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
# use fps to set delay and number of frames to skip (for lower filesized gifs)
|
16
|
+
fps = video_fps(video_location)
|
17
|
+
skip = frame_skip(fps)
|
18
|
+
delay = frame_delay(fps, skip)
|
19
|
+
debug "Capturer: anaimated gif choosing every #{skip} frames with a frame delay of #{delay}"
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
21
|
+
# create the looping animated gif from frames (picks nth frame with seq)
|
22
|
+
seq_command = "seq -f #{frames_location}/%09g.png 1 #{skip} #{Dir["#{frames_location}/*"].length}"
|
23
|
+
# convert to animated gif with delay and gif optimisation
|
24
|
+
system_call "convert -layers OptimizeTransparency -delay #{delay} -loop 0 `#{seq_command}` -coalesce #{snapshot_location}"
|
26
25
|
end
|
27
26
|
|
28
27
|
def executable_path
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'lolcommits/platform'
|
3
|
+
require 'methadone'
|
4
|
+
|
5
|
+
module Lolcommits
|
6
|
+
module CLI
|
7
|
+
# Helper methods for failing on error conditions in the lolcommits CLI.
|
8
|
+
module Fatals
|
9
|
+
include Lolcommits
|
10
|
+
include Methadone::CLILogging
|
11
|
+
|
12
|
+
# Check for platform related conditions that could prevent lolcommits from
|
13
|
+
# working properly.
|
14
|
+
#
|
15
|
+
# Die with an informative error message if any occur.
|
16
|
+
def self.die_on_fatal_platform_conditions!
|
17
|
+
# make sure the capture binaries are in a good state
|
18
|
+
if Platform.platform_mac?
|
19
|
+
%w(imagesnap videosnap).each do |executable|
|
20
|
+
next if File.executable? File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', executable, executable)
|
21
|
+
fatal "Couldn't properly execute #{executable} for some reason, "\
|
22
|
+
'please file a bug?!'
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
elsif Platform.platform_linux?
|
26
|
+
unless Platform.command_which('mplayer')
|
27
|
+
fatal "Couldn't find mplayer in your PATH!"
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# make sure we can find the Impact truetype font
|
33
|
+
unless File.readable? File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'fonts', 'Impact.ttf')
|
34
|
+
fatal "Couldn't properly read Impact font from gem package, "\
|
35
|
+
'please file a bug?!'
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
# make sure imagemagick is around and good to go
|
40
|
+
unless Platform.valid_imagemagick_installed?
|
41
|
+
fatal 'FATAL: ImageMagick does not appear to be properly installed!'\
|
42
|
+
'(or version is too old)'
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
# check for a error condition with git config affecting ruby-git
|
47
|
+
if Platform.git_config_color_always?
|
48
|
+
fatal 'Due to a bug in the ruby-git library, git config for color.ui'\
|
49
|
+
" cannot be set to 'always'."
|
50
|
+
fatal "Try setting it to 'auto' instead!"
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Die with an informative error message if ffmpeg is not installed.
|
56
|
+
# This is only used for certain functions (such as animation), so only run
|
57
|
+
# this when you know the user wants to perform one of them.
|
58
|
+
def self.die_if_no_valid_ffmpeg_installed!
|
59
|
+
unless Platform.valid_ffmpeg_installed?
|
60
|
+
fatal 'FATAL: ffmpeg does not appear to be properly installed!'
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# If we are not in a git repo, we can't do git related things!
|
66
|
+
# Die with an informative error message in that case.
|
67
|
+
def self.die_if_not_git_repo!
|
68
|
+
debug 'Checking for valid git repo'
|
69
|
+
Git.open('.') # FIXME: should be extracted to GitInfo class
|
70
|
+
rescue ArgumentError
|
71
|
+
# ruby-git throws an argument error if path isnt for a valid git repo.
|
72
|
+
fatal "Erm? Can't do that since we're not in a valid git repository!"
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'launchy'
|
3
|
+
|
4
|
+
module Lolcommits
|
5
|
+
module CLI
|
6
|
+
# Helper class for wrapping the opening of files on the desktop in a
|
7
|
+
# cross-platform way.
|
8
|
+
#
|
9
|
+
# Right now this is mostly just a wrapper for Launchy, in case we want
|
10
|
+
# to factor out it's dependency later or swap it out.
|
11
|
+
class Launcher
|
12
|
+
def self.open_image(path)
|
13
|
+
open_with_launchy(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.open_folder(path)
|
17
|
+
open_with_launchy(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Opens with Launchy, which knows how to open pretty much anything
|
21
|
+
# local files, urls, etc.
|
22
|
+
#
|
23
|
+
# Private so we replace it later easier if we want.
|
24
|
+
def self.open_with_launchy(thing)
|
25
|
+
Launchy.open(thing)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Lolcommits
|
4
|
+
module CLI
|
5
|
+
# Helper class for forking lolcommits process to the background (or not).
|
6
|
+
class ProcessRunner
|
7
|
+
# Initializes a new process runner.
|
8
|
+
#
|
9
|
+
# @param config [Lolcommits::Configuration]
|
10
|
+
def initialize(config)
|
11
|
+
@configuration = config
|
12
|
+
end
|
13
|
+
|
14
|
+
# Forks the lolcommits process if requested.
|
15
|
+
#
|
16
|
+
# Writes the PID of the lolcommits process to the filesystem when
|
17
|
+
# backgrounded, for monitoring purposes.
|
18
|
+
#
|
19
|
+
# @param please [Boolean] whether or not to fork lolcommits process
|
20
|
+
# @yield the main event loop for lolcommits
|
21
|
+
def fork_me?(please, &block)
|
22
|
+
if please
|
23
|
+
$stdout.sync = true
|
24
|
+
write_pid fork {
|
25
|
+
yield block
|
26
|
+
delete_pid
|
27
|
+
}
|
28
|
+
else
|
29
|
+
yield block
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def write_pid(pid)
|
36
|
+
File.open(pid_file, 'w') { |f| f.write(pid) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_pid
|
40
|
+
File.delete(pid_file) if File.exist?(pid_file)
|
41
|
+
end
|
42
|
+
|
43
|
+
def pid_file
|
44
|
+
File.join(@configuration.loldir, 'lolcommits.pid')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'lolcommits/cli/fatals'
|
3
|
+
|
4
|
+
require 'mini_magick'
|
5
|
+
|
6
|
+
module Lolcommits
|
7
|
+
module CLI
|
8
|
+
# Creates an animated timeline GIF of lolcommits history.
|
9
|
+
class TimelapseGif
|
10
|
+
# param config [Lolcommits::Configuration]
|
11
|
+
def initialize(config)
|
12
|
+
@configuration = config
|
13
|
+
end
|
14
|
+
|
15
|
+
# Runs the history timeline animator task thingy
|
16
|
+
# param args [String] the arg passed to the gif command on CLI (optional)
|
17
|
+
def run(args = nil)
|
18
|
+
Fatals.die_if_not_git_repo!
|
19
|
+
|
20
|
+
case args
|
21
|
+
when 'today'
|
22
|
+
lolimages = @configuration.jpg_images_today
|
23
|
+
filename = "#{Date.today}.gif"
|
24
|
+
else
|
25
|
+
lolimages = @configuration.jpg_images
|
26
|
+
filename = 'archive.gif'
|
27
|
+
end
|
28
|
+
|
29
|
+
if lolimages.empty?
|
30
|
+
warn 'No lolcommits have been captured for this time yet.'
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
puts '*** Generating animated gif.'
|
35
|
+
|
36
|
+
gif = MiniMagick::Image.new File.join @configuration.archivedir, filename
|
37
|
+
|
38
|
+
# This is for ruby 1.8.7, *lolimages just doesn't work with ruby 187
|
39
|
+
gif.run_command('convert', *['-delay', '50', '-loop', '0', lolimages, "#{gif.path}"].flatten)
|
40
|
+
|
41
|
+
puts "*** #{gif.path} generated."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
|
2
3
|
module Lolcommits
|
3
4
|
class Configuration
|
4
5
|
LOLCOMMITS_BASE = ENV['LOLCOMMITS_DIR'] || File.join(ENV['HOME'], '.lolcommits')
|
@@ -7,20 +8,17 @@ module Lolcommits
|
|
7
8
|
|
8
9
|
def initialize(attributes = {})
|
9
10
|
attributes.each do |attr, val|
|
10
|
-
|
11
|
+
send("#{attr}=", val)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
15
|
def read_configuration
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
nil
|
19
|
-
end
|
16
|
+
return unless File.exist?(configuration_file)
|
17
|
+
YAML.load(File.open(configuration_file))
|
20
18
|
end
|
21
19
|
|
22
20
|
def configuration_file
|
23
|
-
"#{
|
21
|
+
"#{loldir}/config.yml"
|
24
22
|
end
|
25
23
|
|
26
24
|
def loldir
|
@@ -32,51 +30,40 @@ module Lolcommits
|
|
32
30
|
|
33
31
|
def archivedir
|
34
32
|
dir = File.join(loldir, 'archive')
|
35
|
-
|
36
|
-
FileUtils.mkdir_p dir
|
37
|
-
end
|
33
|
+
FileUtils.mkdir_p dir unless File.directory? dir
|
38
34
|
dir
|
39
35
|
end
|
40
36
|
|
41
37
|
def most_recent
|
42
|
-
Dir.glob(File.join
|
38
|
+
Dir.glob(File.join loldir, '*.{jpg,gif}').max_by { |f| File.mtime(f) }
|
43
39
|
end
|
44
40
|
|
45
41
|
def jpg_images
|
46
|
-
Dir.glob(File.join
|
42
|
+
Dir.glob(File.join loldir, '*.jpg').sort_by { |f| File.mtime(f) }
|
47
43
|
end
|
48
44
|
|
49
45
|
def jpg_images_today
|
50
|
-
jpg_images.select { |f| Date.parse(File.mtime(f).to_s)
|
46
|
+
jpg_images.select { |f| Date.parse(File.mtime(f).to_s) == Date.today }
|
51
47
|
end
|
52
48
|
|
53
49
|
def raw_image(image_file_type = 'jpg')
|
54
|
-
File.join
|
50
|
+
File.join loldir, "tmp_snapshot.#{image_file_type}"
|
55
51
|
end
|
56
52
|
|
57
53
|
def main_image(commit_sha, image_file_type = 'jpg')
|
58
|
-
File.join
|
54
|
+
File.join loldir, "#{commit_sha}.#{image_file_type}"
|
59
55
|
end
|
60
56
|
|
61
57
|
def video_loc
|
62
|
-
File.join(
|
58
|
+
File.join(loldir, 'tmp_video.mov')
|
63
59
|
end
|
64
60
|
|
65
61
|
def frames_loc
|
66
|
-
File.join(
|
67
|
-
end
|
68
|
-
|
69
|
-
def puts_devices
|
70
|
-
# TODO: handle other platforms here (linux/windows)
|
71
|
-
if self.class.platform_mac?
|
72
|
-
capturer = Lolcommits::CaptureMacAnimated.new
|
73
|
-
puts `#{capturer.executable_path} -l`
|
74
|
-
puts "Specify a device with --device=\"{device name}\" or set the LOLCOMMITS_DEVICE env variable"
|
75
|
-
end
|
62
|
+
File.join(loldir, 'tmp_frames')
|
76
63
|
end
|
77
64
|
|
78
65
|
def puts_plugins
|
79
|
-
puts "Available plugins: #{Lolcommits::
|
66
|
+
puts "Available plugins: #{Lolcommits::Runner.plugins.map(&:name).join(', ')}"
|
80
67
|
end
|
81
68
|
|
82
69
|
def ask_for_plugin_name
|
@@ -86,10 +73,8 @@ module Lolcommits
|
|
86
73
|
end
|
87
74
|
|
88
75
|
def find_plugin(plugin_name)
|
89
|
-
Lolcommits::
|
90
|
-
if plugin.name == plugin_name
|
91
|
-
return plugin.new(nil)
|
92
|
-
end
|
76
|
+
Lolcommits::Runner.plugins.each do |plugin|
|
77
|
+
return plugin.new(nil) if plugin.name == plugin_name
|
93
78
|
end
|
94
79
|
|
95
80
|
puts "Unable to find plugin: '#{plugin_name}'"
|
@@ -97,30 +82,27 @@ module Lolcommits
|
|
97
82
|
end
|
98
83
|
|
99
84
|
def do_configure!(plugin_name)
|
100
|
-
if plugin_name.to_s.strip.empty?
|
101
|
-
plugin_name = ask_for_plugin_name
|
102
|
-
end
|
85
|
+
plugin_name = ask_for_plugin_name if plugin_name.to_s.strip.empty?
|
103
86
|
|
104
87
|
plugin = find_plugin(plugin_name)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
88
|
+
return unless plugin
|
89
|
+
config = read_configuration || {}
|
90
|
+
plugin_config = plugin.configure_options!
|
91
|
+
# having a plugin_config, means configuring went OK
|
92
|
+
if plugin_config
|
93
|
+
# save plugin and print config
|
94
|
+
config[plugin_name] = plugin_config
|
95
|
+
save(config)
|
96
|
+
puts self
|
97
|
+
puts "\nSuccessfully configured plugin: #{plugin_name}"
|
98
|
+
else
|
99
|
+
puts "\nAborted plugin configuration for: #{plugin_name}"
|
118
100
|
end
|
119
101
|
end
|
120
102
|
|
121
103
|
def save(config)
|
122
104
|
config_file_contents = config.to_yaml
|
123
|
-
File.open(
|
105
|
+
File.open(configuration_file, 'w') do |f|
|
124
106
|
f.write(config_file_contents)
|
125
107
|
end
|
126
108
|
end
|
@@ -131,24 +113,6 @@ module Lolcommits
|
|
131
113
|
|
132
114
|
# class methods
|
133
115
|
|
134
|
-
def self.platform
|
135
|
-
if platform_fakeplatform?
|
136
|
-
ENV['LOLCOMMITS_FAKEPLATFORM']
|
137
|
-
elsif platform_fakecapture?
|
138
|
-
'Fake'
|
139
|
-
elsif platform_mac?
|
140
|
-
'Mac'
|
141
|
-
elsif platform_linux?
|
142
|
-
'Linux'
|
143
|
-
elsif platform_windows?
|
144
|
-
'Windows'
|
145
|
-
elsif platform_cygwin?
|
146
|
-
'Cygwin'
|
147
|
-
else
|
148
|
-
fail 'Unknown / Unsupported Platform.'
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
116
|
def self.loldir_for(basename)
|
153
117
|
loldir = File.join(LOLCOMMITS_BASE, basename)
|
154
118
|
|
@@ -167,72 +131,5 @@ module Lolcommits
|
|
167
131
|
end
|
168
132
|
loldir
|
169
133
|
end
|
170
|
-
|
171
|
-
def self.platform_mac?
|
172
|
-
RUBY_PLATFORM.to_s.downcase.include?('darwin')
|
173
|
-
end
|
174
|
-
|
175
|
-
def self.platform_linux?
|
176
|
-
RUBY_PLATFORM.to_s.downcase.include?('linux')
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.platform_windows?
|
180
|
-
!!RUBY_PLATFORM.match(/(win|w)32/)
|
181
|
-
end
|
182
|
-
|
183
|
-
def self.platform_cygwin?
|
184
|
-
RUBY_PLATFORM.to_s.downcase.include?('cygwin')
|
185
|
-
end
|
186
|
-
|
187
|
-
def self.platform_fakecapture?
|
188
|
-
(ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
|
189
|
-
end
|
190
|
-
|
191
|
-
def self.platform_fakeplatform?
|
192
|
-
ENV['LOLCOMMITS_FAKEPLATFORM']
|
193
|
-
end
|
194
|
-
|
195
|
-
def self.valid_imagemagick_installed?
|
196
|
-
return false unless self.command_which('identify')
|
197
|
-
return false unless self.command_which('mogrify')
|
198
|
-
# you'd expect the below to work on its own, but it only handles old versions
|
199
|
-
# and will throw an exception if IM is not installed in PATH
|
200
|
-
MiniMagick.valid_version_installed?
|
201
|
-
rescue
|
202
|
-
puts "FATAL: ImageMagick >= #{MiniMagick.minimum_image_magick_version} required (http://imagemagick.org)"
|
203
|
-
puts 'Please check the following command works and returns a valid version number'
|
204
|
-
puts '=> mogrify --version'
|
205
|
-
exit 1
|
206
|
-
end
|
207
|
-
|
208
|
-
def self.valid_ffmpeg_installed?
|
209
|
-
self.command_which('ffmpeg')
|
210
|
-
end
|
211
|
-
|
212
|
-
def self.git_config_color_always?
|
213
|
-
`git config color.ui`.chomp =~ /always/
|
214
|
-
end
|
215
|
-
|
216
|
-
def self.can_animate?
|
217
|
-
['Mac', 'Linux'].include? platform
|
218
|
-
end
|
219
|
-
|
220
|
-
# Cross-platform way of finding an executable in the $PATH.
|
221
|
-
# idea taken from http://bit.ly/qDaTbY, if only_path is true, only the path
|
222
|
-
# is returned (not the path and command)
|
223
|
-
#
|
224
|
-
# which('ruby') #=> /usr/bin/ruby
|
225
|
-
def self.command_which(cmd, only_path = false)
|
226
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
227
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
228
|
-
exts.each do |ext|
|
229
|
-
exe = "#{path}/#{cmd}#{ext}"
|
230
|
-
if File.executable? exe
|
231
|
-
return only_path ? path : exe
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
235
|
-
nil
|
236
|
-
end
|
237
134
|
end
|
238
135
|
end
|