lolcommits 0.5.7 → 0.5.8
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/CHANGELOG +11 -0
- 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/core_ext/mini_magick/utilities.rb +15 -0
- 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/capturer.rb +10 -2
- 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/lib/lolcommits.rb +4 -10
- data/lolcommits.gemspec +11 -10
- data/test/lolcommits_test.rb +35 -0
- data/test/plugins_test.rb +52 -0
- metadata +40 -18
- data/test/test_lolcommits.rb +0 -78
|
@@ -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
|
data/lib/lolcommits/git_info.rb
CHANGED
|
@@ -3,50 +3,80 @@ module Lolcommits
|
|
|
3
3
|
class GitInfo
|
|
4
4
|
include Methadone::CLILogging
|
|
5
5
|
attr_accessor :sha, :message, :repo_internal_path, :repo, :url,
|
|
6
|
-
:author_name, :author_email
|
|
6
|
+
:author_name, :author_email, :branch
|
|
7
7
|
|
|
8
|
-
GIT_URL_REGEX =
|
|
8
|
+
GIT_URL_REGEX = %r{.*[:]([\/\w\-]*).git}
|
|
9
9
|
|
|
10
10
|
def initialize
|
|
11
|
-
debug 'GitInfo: attempting to read local repository'
|
|
12
|
-
g = Git.open('.')
|
|
13
|
-
debug 'GitInfo: reading commits logs'
|
|
14
|
-
commit = g.log.first
|
|
15
|
-
debug "GitInfo: most recent commit is '#{commit}'"
|
|
16
|
-
|
|
17
|
-
self.message = commit.message.split("\n").first
|
|
18
|
-
self.sha = commit.sha[0..10]
|
|
19
|
-
self.repo_internal_path = g.repo.path
|
|
20
|
-
|
|
21
|
-
if g.remote.url
|
|
22
|
-
self.url = remote_https_url(g.remote.url)
|
|
23
|
-
match = g.remote.url.match(GIT_URL_REGEX)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
if match
|
|
27
|
-
self.repo = match[1]
|
|
28
|
-
elsif !g.repo.path.empty?
|
|
29
|
-
self.repo = g.repo.path.split(File::SEPARATOR)[-2]
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
if commit.author
|
|
33
|
-
self.author_name = commit.author.name
|
|
34
|
-
self.author_email = commit.author.email
|
|
35
|
-
end
|
|
36
|
-
|
|
37
11
|
debug 'GitInfo: parsed the following values from commit:'
|
|
38
12
|
debug "GitInfo: \t#{message}"
|
|
39
13
|
debug "GitInfo: \t#{sha}"
|
|
40
14
|
debug "GitInfo: \t#{repo_internal_path}"
|
|
41
15
|
debug "GitInfo: \t#{repo}"
|
|
16
|
+
debug "GitInfo: \t#{branch}"
|
|
42
17
|
debug "GitInfo: \t#{author_name}" if author_name
|
|
43
18
|
debug "GitInfo: \t#{author_email}" if author_email
|
|
44
19
|
end
|
|
45
20
|
|
|
21
|
+
def branch
|
|
22
|
+
@branch ||= repository.current_branch
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def message
|
|
26
|
+
@message ||= begin
|
|
27
|
+
message = last_commit.message || ''
|
|
28
|
+
message.split("\n").first
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sha
|
|
33
|
+
@sha ||= last_commit.sha[0..10]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def repo_internal_path
|
|
37
|
+
@repo_internal_path ||= repository.repo.path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def url
|
|
41
|
+
@url ||= begin
|
|
42
|
+
remote_https_url(repository.remote.url) if repository.remote
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def repo
|
|
47
|
+
@repo ||= begin
|
|
48
|
+
if repository.remote && repository.remote.url
|
|
49
|
+
match = repository.remote.url.match(GIT_URL_REGEX)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if match
|
|
53
|
+
match[1]
|
|
54
|
+
elsif !repository.repo.path.empty?
|
|
55
|
+
repository.repo.path.split(File::SEPARATOR)[-2]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def author_name
|
|
61
|
+
@author_name ||= last_commit.author.name if last_commit.author
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def author_email
|
|
65
|
+
@author_email ||= last_commit.author.email if last_commit.author
|
|
66
|
+
end
|
|
67
|
+
|
|
46
68
|
private
|
|
47
69
|
|
|
48
70
|
def remote_https_url(url)
|
|
49
71
|
url.gsub(':', '/').gsub(/^git@/, 'https://').gsub(/\.git$/, '') + '/commit/'
|
|
50
72
|
end
|
|
73
|
+
|
|
74
|
+
def repository(path = '.')
|
|
75
|
+
@repository ||= Git.open(path)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def last_commit
|
|
79
|
+
@commit ||= repository.log.first
|
|
80
|
+
end
|
|
51
81
|
end
|
|
52
82
|
end
|
|
@@ -11,15 +11,13 @@ module Lolcommits
|
|
|
11
11
|
# IF --ENABLE, DO ENABLE
|
|
12
12
|
#
|
|
13
13
|
def self.do_enable
|
|
14
|
-
|
|
14
|
+
unless File.directory?('.git')
|
|
15
15
|
fatal "You don't appear to be in the base directory of a git project."
|
|
16
16
|
exit 1
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# its possible a hooks dir doesnt exist, so create it if so
|
|
20
|
-
|
|
21
|
-
Dir.mkdir(HOOK_DIR)
|
|
22
|
-
end
|
|
20
|
+
Dir.mkdir(HOOK_DIR) unless File.directory?(HOOK_DIR)
|
|
23
21
|
|
|
24
22
|
# should add a shebang (or not) adding will rewrite hook file
|
|
25
23
|
add_shebang = false
|
|
@@ -40,9 +38,7 @@ module Lolcommits
|
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
File.open(HOOK_PATH, add_shebang ? 'w' : 'a') do |f|
|
|
43
|
-
if add_shebang
|
|
44
|
-
f.write("#!/bin/sh\n")
|
|
45
|
-
end
|
|
41
|
+
f.write("#!/bin/sh\n") if add_shebang
|
|
46
42
|
f.write(hook_script)
|
|
47
43
|
end
|
|
48
44
|
|
|
@@ -62,7 +58,7 @@ module Lolcommits
|
|
|
62
58
|
if lolcommits_hook_exists?
|
|
63
59
|
remove_existing_hook!
|
|
64
60
|
info "uninstalled lolcommits hook (from #{HOOK_PATH})"
|
|
65
|
-
elsif File.
|
|
61
|
+
elsif File.exist?(HOOK_PATH)
|
|
66
62
|
info "couldn't find an lolcommits hook (at #{HOOK_PATH})"
|
|
67
63
|
if File.read(HOOK_PATH) =~ /lolcommit/
|
|
68
64
|
info "warning: an older-style lolcommit hook may still exist, edit #{HOOK_PATH} to remove it manually"
|
|
@@ -72,11 +68,9 @@ module Lolcommits
|
|
|
72
68
|
end
|
|
73
69
|
end
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
ruby_path = Lolcommits::Configuration.command_which('ruby', true)
|
|
79
|
-
imagick_path = Lolcommits::Configuration.command_which('identify', true)
|
|
71
|
+
def self.hook_script(_add_shebang = true)
|
|
72
|
+
ruby_path = Lolcommits::Platform.command_which('ruby', true)
|
|
73
|
+
imagick_path = Lolcommits::Platform.command_which('identify', true)
|
|
80
74
|
locale_export = "export LANG=\"#{ENV['LANG']}\"\n"
|
|
81
75
|
hook_export = "export PATH=\"#{ruby_path}:#{imagick_path}:$PATH\"\n"
|
|
82
76
|
capture_cmd = 'lolcommits --capture'
|
|
@@ -91,7 +85,7 @@ EOS
|
|
|
91
85
|
|
|
92
86
|
# does a git hook exist at all?
|
|
93
87
|
def self.hook_file_exists?
|
|
94
|
-
File.
|
|
88
|
+
File.exist?(HOOK_PATH)
|
|
95
89
|
end
|
|
96
90
|
|
|
97
91
|
# does a git hook exist with lolcommits commands?
|
|
@@ -102,7 +96,7 @@ EOS
|
|
|
102
96
|
|
|
103
97
|
# does the git hook file have a good shebang?
|
|
104
98
|
def self.good_shebang?
|
|
105
|
-
File.read(HOOK_PATH).lines.first =~
|
|
99
|
+
File.read(HOOK_PATH).lines.first =~ %r{^\#\!\/bin\/.*sh}
|
|
106
100
|
end
|
|
107
101
|
|
|
108
102
|
def self.remove_existing_hook!
|
|
@@ -111,15 +105,11 @@ EOS
|
|
|
111
105
|
skip = false
|
|
112
106
|
|
|
113
107
|
hook.lines.each do |line|
|
|
114
|
-
if !skip && (line =~ /lolcommits.*\(begin\)/)
|
|
115
|
-
skip = true
|
|
116
|
-
end
|
|
108
|
+
skip = true if !skip && (line =~ /lolcommits.*\(begin\)/)
|
|
117
109
|
|
|
118
110
|
out << line unless skip
|
|
119
111
|
|
|
120
|
-
if skip && (line =~ /lolcommits.*\(end\)/)
|
|
121
|
-
skip = false
|
|
122
|
-
end
|
|
112
|
+
skip = false if skip && (line =~ /lolcommits.*\(end\)/)
|
|
123
113
|
end
|
|
124
114
|
|
|
125
115
|
out.close
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
require 'mini_magick'
|
|
3
|
+
|
|
4
|
+
module Lolcommits
|
|
5
|
+
class Platform
|
|
6
|
+
# A convenience name for the platform. Mainly used for metaprogramming.
|
|
7
|
+
# @return String
|
|
8
|
+
def self.platform
|
|
9
|
+
if platform_fakeplatform? then ENV['LOLCOMMITS_FAKEPLATFORM']
|
|
10
|
+
elsif platform_fakecapture? then 'Fake'
|
|
11
|
+
elsif platform_mac? then 'Mac'
|
|
12
|
+
elsif platform_linux? then 'Linux'
|
|
13
|
+
elsif platform_windows? then 'Windows'
|
|
14
|
+
elsif platform_cygwin? then 'Cygwin'
|
|
15
|
+
else
|
|
16
|
+
fail 'Unknown / Unsupported Platform.'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Are we on a Mac platform?
|
|
21
|
+
# @return Boolean
|
|
22
|
+
def self.platform_mac?
|
|
23
|
+
RUBY_PLATFORM.to_s.downcase.include?('darwin')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Are we on a Linux platform?
|
|
27
|
+
# @return Boolean
|
|
28
|
+
def self.platform_linux?
|
|
29
|
+
RUBY_PLATFORM.to_s.downcase.include?('linux')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Are we on a Windows platform?
|
|
33
|
+
# @return Boolean
|
|
34
|
+
def self.platform_windows?
|
|
35
|
+
!RUBY_PLATFORM.match(/(win|w)32/).nil?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Are we on a Cygwin platform?
|
|
39
|
+
# @return Boolean
|
|
40
|
+
def self.platform_cygwin?
|
|
41
|
+
RUBY_PLATFORM.to_s.downcase.include?('cygwin')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Are we currently faking webcam capture for test purposes?
|
|
45
|
+
# @return Boolean
|
|
46
|
+
def self.platform_fakecapture?
|
|
47
|
+
(ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Are we currently overriding and faking the platform entirely?
|
|
51
|
+
# @todo possibly make this a private method?
|
|
52
|
+
# @return Boolean
|
|
53
|
+
def self.platform_fakeplatform?
|
|
54
|
+
ENV['LOLCOMMITS_FAKEPLATFORM']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Is the platform capable of capturing animated GIFs from webcam?
|
|
58
|
+
# @return Boolean
|
|
59
|
+
def self.can_animate?
|
|
60
|
+
# FIXME: this is currently matching against string instead of
|
|
61
|
+
# simply returning platform_mac? || platform_linux?
|
|
62
|
+
# This is not ideal... but otherwise overriding platform via
|
|
63
|
+
# LOLCOMMITS_FAKEPLATFORM when running cucumber tests won't work.
|
|
64
|
+
# We should come up with a better solution.
|
|
65
|
+
%w(Mac Linux).include? platform
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Is a valid install of imagemagick present on the system?
|
|
69
|
+
# @return Boolean
|
|
70
|
+
def self.valid_imagemagick_installed?
|
|
71
|
+
return false unless command_which('identify')
|
|
72
|
+
return false unless command_which('mogrify')
|
|
73
|
+
# you'd expect the below to work on its own, but it only handles old versions
|
|
74
|
+
# and will throw an exception if IM is not installed in PATH
|
|
75
|
+
MiniMagick.valid_version_installed?
|
|
76
|
+
rescue
|
|
77
|
+
return false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Is a valid install of ffmpeg present on the system?
|
|
81
|
+
#
|
|
82
|
+
# @note For now, this just checks for presence, any version should work.
|
|
83
|
+
# @return Boolean
|
|
84
|
+
def self.valid_ffmpeg_installed?
|
|
85
|
+
command_which('ffmpeg')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Cross-platform way of finding an executable in the $PATH.
|
|
89
|
+
#
|
|
90
|
+
# Idea taken from http://bit.ly/qDaTbY, if only_path is true, only the path
|
|
91
|
+
# is returned (not the path and command)
|
|
92
|
+
#
|
|
93
|
+
# @example
|
|
94
|
+
# command_which('ruby') #=> /usr/bin/ruby
|
|
95
|
+
#
|
|
96
|
+
# @return Boolean
|
|
97
|
+
def self.command_which(cmd, only_path = false)
|
|
98
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
99
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
100
|
+
exts.each do |ext|
|
|
101
|
+
exe = "#{path}/#{cmd}#{ext}"
|
|
102
|
+
return only_path ? path : exe if File.executable? exe
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Is `git config color.ui` set to 'always'?
|
|
109
|
+
#
|
|
110
|
+
# Due to a bug in the ruby-git library, git config for color.ui cannot be
|
|
111
|
+
# set to 'always' or it won't read properly.
|
|
112
|
+
#
|
|
113
|
+
# This helper method let's us check for that error condition so we can
|
|
114
|
+
# alert the user in the CLI tool.
|
|
115
|
+
#
|
|
116
|
+
# @return Boolean
|
|
117
|
+
def self.git_config_color_always?
|
|
118
|
+
`git config color.ui`.chomp =~ /always/
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Returns a list of system camera devices in a format suitable to display
|
|
122
|
+
# to the user.
|
|
123
|
+
#
|
|
124
|
+
# @note Currently only functions on Mac.
|
|
125
|
+
# @return String
|
|
126
|
+
def self.device_list
|
|
127
|
+
# TODO: handle other platforms here (linux/windows)
|
|
128
|
+
if Platform.platform_mac?
|
|
129
|
+
capturer = Lolcommits::CaptureMacAnimated.new
|
|
130
|
+
`#{capturer.executable_path} -l`
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
data/lib/lolcommits/plugin.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Lolcommits
|
|
|
46
46
|
# ask for plugin options
|
|
47
47
|
def configure_options!
|
|
48
48
|
puts "Configuring plugin: #{self.class.name}\n"
|
|
49
|
-
options.reduce(
|
|
49
|
+
options.reduce({}) do |acc, option|
|
|
50
50
|
print "#{option}: "
|
|
51
51
|
val = parse_user_input(STDIN.gets.strip)
|
|
52
52
|
# check enabled option isn't a String
|
|
@@ -103,7 +103,7 @@ module Lolcommits
|
|
|
103
103
|
|
|
104
104
|
# uniform debug logging for plugins
|
|
105
105
|
def debug(msg)
|
|
106
|
-
super("Plugin: #{self.class
|
|
106
|
+
super("Plugin: #{self.class}: " + msg)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# identifying plugin name (for config, listing)
|
|
@@ -7,27 +7,27 @@ module Lolcommits
|
|
|
7
7
|
|
|
8
8
|
def initialize(runner)
|
|
9
9
|
super
|
|
10
|
-
|
|
10
|
+
options.concat(%w(api_key api_secret repo_id))
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def run_postcapture
|
|
14
14
|
return unless valid_configuration?
|
|
15
15
|
|
|
16
16
|
t = Time.now.to_i.to_s
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
HTTMultiParty.post(
|
|
18
|
+
"#{BASE_URL}/git_commits.json",
|
|
19
|
+
:body => {
|
|
20
|
+
:git_commit => {
|
|
21
|
+
:sha => runner.sha,
|
|
22
|
+
:repo_external_id => configuration['repo_id'],
|
|
23
|
+
:image => File.open(runner.main_image),
|
|
24
|
+
:raw => File.open(runner.snapshot_loc)
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
:key => configuration['api_key'],
|
|
28
|
+
:t => t,
|
|
29
|
+
:token => Digest::SHA1.hexdigest(configuration['api_secret'] + t)
|
|
30
|
+
})
|
|
31
31
|
rescue => e
|
|
32
32
|
log_error(e, "ERROR: HTTMultiParty POST FAILED #{e.class} - #{e.message}")
|
|
33
33
|
end
|