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
|
@@ -1,122 +1,142 @@
|
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
|
2
|
-
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'aruba/api'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
def postcommit_hook
|
|
6
|
+
'.git/hooks/post-commit'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def default_repo
|
|
10
|
+
'mygit'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def default_loldir
|
|
14
|
+
absolute_path("~/.lolcommits/#{default_repo}")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Given(/^I am in a directory named "(.*?)"$/) do |dir_name|
|
|
18
|
+
steps %(
|
|
6
19
|
Given a directory named "#{dir_name}"
|
|
7
20
|
And I cd to "#{dir_name}"
|
|
8
|
-
|
|
21
|
+
)
|
|
9
22
|
end
|
|
10
23
|
|
|
11
|
-
Given
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
system 'git init --quiet .'
|
|
16
|
-
system "git config user.name 'Testy McTesterson'"
|
|
17
|
-
system "git config user.email 'testy@tester.com'"
|
|
18
|
-
end
|
|
24
|
+
Given(/^a git repo named "(.*?)"$/) do |repo_name|
|
|
25
|
+
steps %(
|
|
26
|
+
Given I successfully run `git init --quiet "#{repo_name}"`
|
|
27
|
+
)
|
|
19
28
|
end
|
|
20
29
|
|
|
21
|
-
Given
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
Given(/^I am in a git repo named "(.*?)"$/) do |repo|
|
|
31
|
+
steps %(
|
|
32
|
+
Given a git repo named "#{repo}"
|
|
33
|
+
And I cd to "#{repo}"
|
|
34
|
+
)
|
|
24
35
|
end
|
|
25
36
|
|
|
26
|
-
Given
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
Given(/^I am in a git repo$/) do
|
|
38
|
+
steps %(
|
|
39
|
+
Given I am in a git repo named "#{default_repo}"
|
|
40
|
+
)
|
|
29
41
|
end
|
|
30
42
|
|
|
31
|
-
Given
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
Given(/^I am in a git repo named "(.*?)" with lolcommits enabled$/) do |repo|
|
|
44
|
+
steps %(
|
|
45
|
+
Given I am in a git repo named "#{repo}"
|
|
46
|
+
And I successfully run `lolcommits --enable`
|
|
47
|
+
)
|
|
35
48
|
end
|
|
36
49
|
|
|
37
|
-
Given
|
|
38
|
-
|
|
39
|
-
|
|
50
|
+
Given(/^I am in a git repo with lolcommits enabled$/) do
|
|
51
|
+
steps %(
|
|
52
|
+
Given I am in a git repo named "#{default_repo}" with lolcommits enabled
|
|
53
|
+
)
|
|
40
54
|
end
|
|
41
55
|
|
|
42
|
-
Given
|
|
43
|
-
steps %
|
|
44
|
-
Given a
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
Given(/^a post\-commit hook with "(.*?)"$/) do |file_content|
|
|
57
|
+
steps %(
|
|
58
|
+
Given a file named "#{postcommit_hook}" with:
|
|
59
|
+
"""
|
|
60
|
+
#{file_content}
|
|
61
|
+
"""
|
|
62
|
+
)
|
|
47
63
|
end
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
steps %
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
Then(/^the lolcommits post\-commit hook should be properly installed$/) do
|
|
66
|
+
steps %(
|
|
67
|
+
Then the post-commit hook should contain "lolcommits --capture"
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
Then(/^the post\-commit hook (should|should not) contain "(.*?)"$/) do |should, content|
|
|
72
|
+
steps %(
|
|
73
|
+
Then the file "#{postcommit_hook}" #{should} contain "#{content}"
|
|
74
|
+
)
|
|
54
75
|
end
|
|
55
76
|
|
|
56
|
-
Given
|
|
77
|
+
Given(/^I have environment variable (.*?) set to (.*?)$/) do |var, value|
|
|
57
78
|
set_env var, value
|
|
58
79
|
end
|
|
59
80
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
Given(/^its loldir has (\d+) lolimages$/) do |num_images|
|
|
82
|
+
steps %(
|
|
83
|
+
Given a loldir named "#{default_repo}" with #{num_images} lolimages
|
|
84
|
+
)
|
|
64
85
|
end
|
|
65
86
|
|
|
66
|
-
Given
|
|
67
|
-
loldir = "
|
|
68
|
-
mkdir_p loldir
|
|
87
|
+
Given(/^a loldir named "(.*?)" with (\d+) lolimages$/) do |repo, num_images|
|
|
88
|
+
loldir = absolute_path("~/.lolcommits/#{repo}")
|
|
89
|
+
FileUtils.mkdir_p loldir
|
|
69
90
|
num_images.to_i.times do
|
|
70
|
-
|
|
71
|
-
cp 'test/images/test_image.jpg', File.join(loldir, "#{
|
|
91
|
+
hex = "#{format '%011x', (rand * 0xfffffffffff)}"
|
|
92
|
+
FileUtils.cp 'test/images/test_image.jpg', File.join(loldir, "#{hex}.jpg")
|
|
72
93
|
end
|
|
73
94
|
end
|
|
74
95
|
|
|
75
|
-
Then
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
When /^I enter "(.*?)" for "(.*?)"$/ do |input, field|
|
|
80
|
-
@fields[field] = input
|
|
81
|
-
@stdin.puts input
|
|
96
|
+
Then(/^there should be exactly (.*?) (jpg|gif|pid)s? in its loldir$/) do |n, type|
|
|
97
|
+
steps %(
|
|
98
|
+
Then there should be exactly #{n} #{type} in "#{default_loldir}"
|
|
99
|
+
)
|
|
82
100
|
end
|
|
83
101
|
|
|
84
|
-
Then
|
|
85
|
-
|
|
102
|
+
Then(/^there should be exactly (.*?) (jpg|gif|pid)s? in "(.*?)"$/) do |n, type, folder|
|
|
103
|
+
expect(Dir[absolute_path(folder, "*.#{type}")].count).to eq(n.to_i)
|
|
86
104
|
end
|
|
87
105
|
|
|
88
|
-
Then
|
|
89
|
-
step %
|
|
106
|
+
Then(/^the output should contain a list of plugins$/) do
|
|
107
|
+
step %(the output should contain "Available plugins: ")
|
|
90
108
|
end
|
|
91
109
|
|
|
92
|
-
When
|
|
110
|
+
When(/^I do a git commit with commit message "(.*?)"$/) do |commit_msg|
|
|
93
111
|
filename = Faker::Lorem.words(1).first
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
steps %(
|
|
113
|
+
Given a 98 byte file named "#{filename}"
|
|
114
|
+
And I successfully run `git add #{filename}`
|
|
115
|
+
And I successfully run `git commit -m "#{commit_msg}"`
|
|
116
|
+
)
|
|
97
117
|
end
|
|
98
118
|
|
|
99
|
-
When
|
|
100
|
-
|
|
101
|
-
step %{I do a git commit with commit message "#{commit_msg}"}
|
|
119
|
+
When(/^I do a git commit$/) do
|
|
120
|
+
step %(I do a git commit with commit message "#{Faker::Lorem.sentence}")
|
|
102
121
|
end
|
|
103
122
|
|
|
104
|
-
When
|
|
123
|
+
When(/^I do (\d+) git commits$/) do |n|
|
|
105
124
|
n.to_i.times do
|
|
106
|
-
step %
|
|
125
|
+
step %(I do a git commit)
|
|
107
126
|
sleep 0.1
|
|
108
127
|
end
|
|
109
128
|
end
|
|
110
129
|
|
|
111
|
-
Then
|
|
130
|
+
Then(/^there should be (\d+) commit entries in the git log$/) do |n|
|
|
112
131
|
sleep 1 # let the file writing catch up
|
|
113
|
-
|
|
132
|
+
expect(n.to_i).to eq `git shortlog | grep -E '^[ ]+\w+' | wc -l`.chomp.to_i
|
|
114
133
|
end
|
|
115
134
|
|
|
116
|
-
Given
|
|
117
|
-
|
|
135
|
+
Given(/^I am using a "(.*?)" platform$/) do |platform_name|
|
|
136
|
+
set_env 'LOLCOMMITS_FAKEPLATFORM', platform_name
|
|
118
137
|
end
|
|
119
138
|
|
|
120
|
-
When
|
|
121
|
-
|
|
139
|
+
When(/^I wait for the child process to exit in "(.*?)"$/) do |repo_name|
|
|
140
|
+
pid_loc = absolute_path("~/.lolcommits/#{repo_name}/lolcommits.pid")
|
|
141
|
+
sleep 0.1 while File.exist?(pid_loc)
|
|
122
142
|
end
|
data/features/support/env.rb
CHANGED
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
require 'aruba/cucumber'
|
|
3
3
|
require 'methadone/cucumber'
|
|
4
4
|
require 'open3'
|
|
5
|
-
require 'test/unit/assertions'
|
|
6
|
-
include Test::Unit::Assertions
|
|
7
5
|
require 'ffaker'
|
|
8
|
-
require '
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
|
|
9
8
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'path_helpers')
|
|
10
9
|
include Lolcommits
|
|
11
10
|
|
|
12
|
-
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
|
13
|
-
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'lib')
|
|
14
|
-
|
|
15
11
|
World(PathHelpers)
|
|
16
12
|
|
|
17
13
|
Before do
|
|
@@ -19,70 +15,44 @@ Before do
|
|
|
19
15
|
@puts = true
|
|
20
16
|
@aruba_timeout_seconds = 20
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@original_fakecapture = ENV['LOLCOMMITS_FAKECAPTURE']
|
|
26
|
-
ENV['LOLCOMMITS_FAKECAPTURE'] = '1'
|
|
27
|
-
|
|
28
|
-
# @original_loldir = ENV['LOLCOMMITS_DIR']
|
|
29
|
-
# ENV['LOLCOMMITS_DIR'] = File.expand_path( File.join(current_dir, ".lolcommits") )
|
|
30
|
-
|
|
31
|
-
@original_home = ENV['HOME']
|
|
32
|
-
ENV['HOME'] = File.expand_path(current_dir)
|
|
33
|
-
|
|
34
|
-
ENV['LAUNCHY_DRY_RUN'] = 'true'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
After do
|
|
38
|
-
ENV['RUBYLIB'] = @original_rubylib
|
|
39
|
-
ENV['LOLCOMMITS_FAKECAPTURE'] = @original_fakecapture
|
|
40
|
-
# ENV['LOLCOMMITS_DIR'] = @original_loldir
|
|
41
|
-
ENV['HOME'] = @original_home
|
|
42
|
-
ENV['LAUNCHY_DRY_RUN'] = nil
|
|
43
|
-
ENV['LOLCOMMITS_FAKEPLATFORM'] = nil
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
Before('@fake-interactive-rebase') do
|
|
47
|
-
# in order to fake an interactive rebase,
|
|
48
|
-
# we replace the editor with a script that simply squashes a few random commits
|
|
49
|
-
@original_git_editor = ENV['GIT_EDITOR']
|
|
50
|
-
# ENV['GIT_EDITOR'] = "sed -i -e 'n;s/pick/squash/g'" #every other commit
|
|
51
|
-
ENV['GIT_EDITOR'] = "sed -i -e '3,5 s/pick/squash/g'" # lines 3-5
|
|
52
|
-
end
|
|
18
|
+
set_env 'LOLCOMMITS_FAKECAPTURE', '1'
|
|
19
|
+
set_env 'LAUNCHY_DRY_RUN', 'true'
|
|
53
20
|
|
|
54
|
-
|
|
55
|
-
|
|
21
|
+
author_name = 'Testy McTesterson'
|
|
22
|
+
author_email = 'testy@tester.com'
|
|
23
|
+
set_env 'GIT_AUTHOR_NAME', author_name
|
|
24
|
+
set_env 'GIT_COMMITTER_NAME', author_name
|
|
25
|
+
set_env 'GIT_AUTHOR_EMAIL', author_email
|
|
26
|
+
set_env 'GIT_COMMITTER_EMAIL', author_email
|
|
56
27
|
end
|
|
57
28
|
|
|
29
|
+
# for tasks that may take an insanely long time (e.g. network related)
|
|
30
|
+
# we should strive to not have any of these in our scenarios, naturally.
|
|
58
31
|
Before('@slow_process') do
|
|
59
32
|
@aruba_io_wait_seconds = 5
|
|
60
33
|
@aruba_timeout_seconds = 60
|
|
61
34
|
end
|
|
62
35
|
|
|
36
|
+
# in order to fake an interactive rebase, we replace the editor with a script
|
|
37
|
+
# to simply squash a few random commits. in this case, using lines 3-5.
|
|
38
|
+
Before('@fake-interactive-rebase') do
|
|
39
|
+
set_env 'GIT_EDITOR', "sed -i -e '3,5 s/pick/squash/g'"
|
|
40
|
+
end
|
|
41
|
+
|
|
63
42
|
# adjust the path so tests dont see a global imagemagick install
|
|
64
43
|
Before('@fake-no-imagemagick') do
|
|
65
44
|
reject_paths_with_cmd('mogrify')
|
|
66
45
|
end
|
|
67
46
|
|
|
68
|
-
After('@fake-no-imagemagick') do
|
|
69
|
-
reset_path
|
|
70
|
-
end
|
|
71
|
-
|
|
72
47
|
# adjust the path so tests dont see a global ffmpeg install
|
|
73
48
|
Before('@fake-no-ffmpeg') do
|
|
74
49
|
reject_paths_with_cmd('ffmpeg')
|
|
75
50
|
end
|
|
76
51
|
|
|
77
|
-
After('@fake-no-ffmpeg') do
|
|
78
|
-
reset_path
|
|
79
|
-
end
|
|
80
|
-
|
|
81
52
|
# do test in temporary directory so our own git repo-ness doesn't affect it
|
|
82
53
|
Before('@in-tempdir') do
|
|
83
54
|
@dirs = [Dir.mktmpdir]
|
|
84
55
|
end
|
|
85
|
-
|
|
86
56
|
After('@in-tempdir') do
|
|
87
57
|
FileUtils.rm_rf(@dirs.first)
|
|
88
58
|
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'aruba/api'
|
|
4
|
+
require 'lolcommits/platform'
|
|
5
|
+
|
|
2
6
|
module PathHelpers
|
|
3
7
|
def reject_paths_with_cmd(cmd)
|
|
4
|
-
@original_path = ENV['PATH']
|
|
5
8
|
# make a new subdir that still contains cmds
|
|
6
9
|
tmpbindir = File.expand_path(File.join @dirs, 'bin')
|
|
7
10
|
FileUtils.mkdir_p tmpbindir
|
|
8
11
|
|
|
9
|
-
preseve_cmds_in_path(
|
|
12
|
+
preseve_cmds_in_path(%w(git mplayer), tmpbindir)
|
|
10
13
|
|
|
11
14
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
12
15
|
newpaths = ENV['PATH'].split(File::PATH_SEPARATOR).reject do |path|
|
|
@@ -20,19 +23,17 @@ module PathHelpers
|
|
|
20
23
|
|
|
21
24
|
# add the temporary directory with git in it back into the path
|
|
22
25
|
newpaths << tmpbindir
|
|
23
|
-
|
|
26
|
+
|
|
27
|
+
# use aruba/api set_env to set PATH, which will be automaticaly restored
|
|
28
|
+
set_env 'PATH', newpaths.join(File::PATH_SEPARATOR)
|
|
24
29
|
end
|
|
25
30
|
|
|
26
31
|
def preseve_cmds_in_path(cmds, tmpbindir)
|
|
27
32
|
cmds.each do |cmd|
|
|
28
|
-
whichcmd = Lolcommits::
|
|
33
|
+
whichcmd = Lolcommits::Platform.command_which(cmd)
|
|
29
34
|
unless whichcmd.nil?
|
|
30
35
|
FileUtils.ln_s whichcmd, File.join(tmpbindir, File.basename(whichcmd))
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
|
-
|
|
35
|
-
def reset_path
|
|
36
|
-
ENV['PATH'] = @original_path
|
|
37
|
-
end
|
|
38
39
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
# To maintain MiniMagick compatibility on Windows for v3.8.1 we need this patch
|
|
3
|
+
# If/when we upgrade MiniMagick to 4.2+ this patch can be removed
|
|
4
|
+
# We are locked at v3.8.1 since MiniMagick 4+ dropped support for Ruby 1.8.7
|
|
5
|
+
module MiniMagick
|
|
6
|
+
module Utilities
|
|
7
|
+
class << self
|
|
8
|
+
# fixes issue introduced in this commit
|
|
9
|
+
# https://github.com/minimagick/minimagick/commit/65b6427395cbfe6
|
|
10
|
+
def windows_escape(cmdline)
|
|
11
|
+
'"' + cmdline.gsub(/\\(?=\\*\")/, '\\\\\\').gsub(/\"/, '\\"').gsub(/\\$/, '\\\\\\').gsub('%', '%%') + '"'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -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
|
data/lib/lolcommits/capturer.rb
CHANGED
|
@@ -8,9 +8,17 @@ module Lolcommits
|
|
|
8
8
|
|
|
9
9
|
def initialize(attributes = {})
|
|
10
10
|
attributes.each do |attr, val|
|
|
11
|
-
|
|
11
|
+
send("#{attr}=", val)
|
|
12
12
|
end
|
|
13
|
-
debug 'Capturer: initializing new instance ' +
|
|
13
|
+
debug 'Capturer: initializing new instance ' + to_s
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
require 'lolcommits/capturer/capture_mac'
|
|
19
|
+
require 'lolcommits/capturer/capture_mac_animated'
|
|
20
|
+
require 'lolcommits/capturer/capture_linux'
|
|
21
|
+
require 'lolcommits/capturer/capture_linux_animated'
|
|
22
|
+
require 'lolcommits/capturer/capture_windows'
|
|
23
|
+
require 'lolcommits/capturer/capture_cygwin'
|
|
24
|
+
require 'lolcommits/capturer/capture_fake'
|
|
@@ -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
|