lolcommits 0.2.0 → 0.3.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ Feature: Plugins Work
2
+
3
+ Scenario: Lolcommits.com integration works
4
+ Given a git repository named "dot_com"
5
+ And an empty file named "dot_com/FOOBAR"
6
+ When I cd to "dot_com"
7
+ And I successfully run `lolcommits --enable`
8
+ And I run `lolcommits --config` and wait for output
9
+ And I enter "dot_com" for "Plugin Name"
10
+ And I enter "true" for "enabled"
11
+ And I enter "b2a70ac0b64e012fa61522000a8c42dc" for "api_key"
12
+ And I enter "b2a720b0b64e012fa61522000a8c42dc" for "api_secret"
13
+ And I enter "c4aed530b64e012fa61522000a8c42dc" for "repo_id"
14
+ Then I should be presented "Successfully Configured"
15
+ When I successfully run `git add .`
16
+ And I successfully run `git commit -m 'can haz commit'`
17
+ Then the output should contain "*** Preserving this moment in history."
18
+ And there should be 1 jpg in "../.lolcommits/dot_com"
19
+
20
+ Scenario: Disable loltext
21
+ Given a git repository named "loltext"
22
+ And an empty file named "loltext/FOOBAR"
23
+ When I cd to "loltext"
24
+ And I successfully run `lolcommits --enable`
25
+ And I run `lolcommits --config` and wait for output
26
+ And I enter "loltext" for "Plugin Name"
27
+ And I enter "false" for "enabled"
28
+ Then I should be presented "Successfully Configured"
29
+ When I successfully run `git add .`
30
+ And I successfully run `git commit -m 'can haz commit'`
31
+ Then the output should contain "*** Preserving this moment in history."
32
+ And there should be 1 jpg in "../.lolcommits/loltext"
33
+
@@ -18,3 +18,40 @@ Given /^the git repository named "(.*?)" has a "(.*?)" hook$/ do |repo_name, hoo
18
18
  hook_file = File.join current_dir, repo_name, ".git", "hooks", hook_name
19
19
  touch(hook_file) if not File.exists? hook_file
20
20
  end
21
+
22
+ Given /^a git repository named "(.*?)" with (a|no) "(.*?)" hook$/ do |repo_name, yesno_modifier, hook_name|
23
+ step %{a git repository named "#{repo_name}"}
24
+ step %{the git repository named "#{repo_name}" has #{yesno_modifier} "#{hook_name}" hook}
25
+ end
26
+
27
+ When /^I run `(.*?)` and wait for output$/ do |command|
28
+ command = "cd #{current_dir} && #{command}"
29
+ @stdin, @stdout, @stderr = Open3.popen3(command)
30
+ @fields = Hash.new
31
+ end
32
+
33
+ Given /^a loldir named "(.*?)" with (\d+) lolimages$/ do |repo_name, num_images|
34
+ loldir = "tmp/aruba/.lolcommits/#{repo_name}"
35
+ mkdir_p loldir
36
+ num_images.to_i.times do
37
+ random_hex = "%011x" % (rand * 0xfffffffffff)
38
+ cp "test/images/test_image.jpg", File.join( loldir, "#{random_hex}.jpg")
39
+ end
40
+ end
41
+
42
+ Then /^I should be (prompted for|presented) "(.*?)"$/ do |_, prompt|
43
+ assert @stdout.read.to_s.include?(prompt)
44
+ end
45
+
46
+ When /^I enter "(.*?)" for "(.*?)"$/ do |input, field|
47
+ @fields[field] = input
48
+ @stdin.puts input
49
+ end
50
+
51
+ Then /^there should be (.*?) jpg(|s) in "(.*?)"$/ do |n, _, folder|
52
+ assert_equal n.to_i, Dir["#{current_dir}/#{folder}/*.jpg"].count
53
+ end
54
+
55
+ Then /^the output should contain a list of plugins$/ do
56
+ step %{the output should contain "Available plugins: "}
57
+ end
@@ -1,5 +1,8 @@
1
1
  require 'aruba/cucumber'
2
2
  require 'methadone/cucumber'
3
+ require 'open3'
4
+ require 'test/unit/assertions'
5
+ include Test::Unit::Assertions
3
6
 
4
7
  ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
5
8
  LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
@@ -8,18 +11,35 @@ Before do
8
11
  # Using "announce" causes massive warnings on 1.9.2
9
12
  @puts = true
10
13
  @original_rubylib = ENV['RUBYLIB']
14
+ @aruba_timeout_seconds = 20
11
15
  ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
12
- end
13
-
14
- After do
15
- ENV['RUBYLIB'] = @original_rubylib
16
- end
17
16
 
18
- Before('@simulate-capture') do
19
17
  @original_fakecapture = ENV['LOLCOMMITS_FAKECAPTURE']
20
18
  ENV['LOLCOMMITS_FAKECAPTURE'] = "1"
19
+
20
+ @original_loldir = ENV['LOLCOMMITS_DIR']
21
+ ENV['LOLCOMMITS_DIR'] = File.expand_path( File.join(current_dir, ".lolcommits") )
22
+
23
+ ENV['LAUNCHY_DRY_RUN'] = 'true'
21
24
  end
22
25
 
23
- After('@simulate-capture') do
26
+ After do
27
+ ENV['RUBYLIB'] = @original_rubylib
24
28
  ENV['LOLCOMMITS_FAKECAPTURE'] = @original_fakecapture
29
+ ENV['LOLCOMMITS_DIR'] = @original_loldir
30
+ ENV['LAUNCHY_DRY_RUN'] = nil
25
31
  end
32
+
33
+ # ###moved the below into env for everything
34
+ # Before('@simulate-env') do
35
+ # @original_fakecapture = ENV['LOLCOMMITS_FAKECAPTURE']
36
+ # ENV['LOLCOMMITS_FAKECAPTURE'] = "1"
37
+
38
+ # @original_loldir = ENV['LOLCOMMITS_DIR']
39
+ # ENV['LOLCOMMITS_DIR'] = File.join(current_dir, ".lolcommits")
40
+ # end
41
+
42
+ # After('@simulate-env') do
43
+ # ENV['LOLCOMMITS_FAKECAPTURE'] = @original_fakecapture
44
+ # ENV['LOLCOMMITS_DIR'] = @original_loldir
45
+ # end
@@ -0,0 +1,7 @@
1
+ class Class
2
+ def subclasses
3
+ result = []
4
+ ObjectSpace.each_object(Class) { |klass| result << klass if klass < self }
5
+ result
6
+ end
7
+ end
@@ -1,180 +1,26 @@
1
1
  $:.unshift File.expand_path('.')
2
2
 
3
- require "lolcommits/version"
4
- require "tranzlate/lolspeak"
5
- require "choice"
6
- require "fileutils"
7
- require "git"
8
- require "RMagick"
9
- require "open3"
10
- require "launchy"
11
- include Magick
12
-
13
- module Lolcommits
14
- $home = ENV['HOME']
15
- LOLBASEDIR = File.join $home, ".lolcommits"
16
- LOLCOMMITS_ROOT = File.join(File.dirname(__FILE__), '..')
17
-
18
- def is_mac?
19
- RUBY_PLATFORM.downcase.include?("darwin")
20
- end
21
-
22
- def is_linux?
23
- RUBY_PLATFORM.downcase.include?("linux")
24
- end
25
-
26
- def is_windows?
27
- if RUBY_PLATFORM =~ /(win|w)32$/
28
- true
29
- end
30
- end
31
-
32
- def is_fakecapture?
33
- (ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
34
- end
35
-
36
- def most_recent(dir='.')
37
- loldir, commit_sha, commit_msg = parse_git
38
- Dir.glob(File.join loldir, "*").max_by {|f| File.mtime(f)}
39
- end
40
-
41
- def loldir(dir='.')
42
- loldir, commit_sha, commit_msg = parse_git
43
- return loldir
44
- end
45
-
46
- def parse_git(dir='.')
47
- g = Git.open('.')
48
- commit = g.log.first
49
- commit_msg = commit.message.split("\n").first
50
- commit_sha = commit.sha[0..10]
51
- basename = File.basename(g.dir.to_s)
52
- basename.sub!(/^\./, 'dot') #no invisible directories in output, thanks!
53
- loldir = File.join LOLBASEDIR, basename
54
- return loldir, commit_sha, commit_msg
55
- end
56
-
57
- def capture(capture_delay=0, capture_device=nil, is_test=false, test_msg=nil, test_sha=nil)
58
- #
59
- # Read the git repo information from the current working directory
60
- #
61
- if not is_test
62
- loldir, commit_sha, commit_msg = parse_git
63
- else
64
- commit_msg = test_msg
65
- commit_sha = test_sha
66
- loldir = File.join LOLBASEDIR, "test"
67
- end
68
-
69
- #
70
- # lolspeak translate the message
71
- #
72
- if (ENV['LOLCOMMITS_TRANZLATE'] == '1' || false)
73
- commit_msg = commit_msg.tranzlate
74
- end
75
-
76
- #
77
- # Create a directory to hold the lolimages
78
- #
79
- if not File.directory? loldir
80
- FileUtils.mkdir_p loldir
81
- end
82
-
83
- #
84
- # SMILE FOR THE CAMERA! 3...2...1...
85
- # We're just assuming the captured image is 640x480 for now, we may
86
- # need updates to the imagesnap program to manually set this (or resize)
87
- # if this changes on future mac isights.
88
- #
89
- puts "*** Preserving this moment in history."
90
- snapshot_loc = File.join loldir, "tmp_snapshot.jpg"
91
- # if (ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
92
- if is_fakecapture?
93
- test_image = File.join LOLCOMMITS_ROOT, "test", "images", "test_image.jpg"
94
- FileUtils.cp test_image, snapshot_loc
95
- elsif is_mac?
96
- imagesnap_bin = File.join LOLCOMMITS_ROOT, "ext", "imagesnap", "imagesnap"
97
- capture_device = "-d '#{capture_device}'" if capture_device
98
- system("#{imagesnap_bin} -q #{snapshot_loc} -w #{capture_delay} #{capture_device}")
99
- elsif is_linux?
100
- tmpdir = File.expand_path "#{loldir}/tmpdir#{rand(1000)}/"
101
- FileUtils.mkdir_p( tmpdir )
102
- # There's no way to give a capture delay in mplayer, but a number of frame
103
- # I've found that 6 is a good value for me.
104
- frames = if capture_delay != 0 then capture_delay else 6 end
105
-
106
- # mplayer's output is ugly and useless, let's throw it away
107
- _, r, _ = Open3.popen3("mplayer -vo jpeg:outdir=#{tmpdir} -frames #{frames} tv://")
108
- # looks like we still need to read the output for something to happen
109
- r.read
110
- FileUtils.mv(tmpdir + "/%08d.jpg" % frames, snapshot_loc)
111
- FileUtils.rm_rf( tmpdir )
112
- elsif is_windows?
113
- commandcam_exe = File.join LOLCOMMITS_ROOT, "ext", "CommandCam", "CommandCam.exe"
114
- # DirectShow takes a while to show... at least for me anyway
115
- delaycmd = " /delay 3000"
116
- if capture_delay > 0
117
- # CommandCam delay is in milliseconds
118
- delaycmd = " /delay #{capture_delay * 1000}"
119
- end
120
- _, r, _ = Open3.popen3("#{commandcam_exe} /filename #{snapshot_loc}#{delaycmd}")
121
- # looks like we still need to read the output for something to happen
122
- r.read
123
- end
124
-
125
-
126
- #
127
- # Process the image with ImageMagick to add loltext
128
- #
129
-
130
- # read in the image, and resize it via the canvas
131
- canvas = ImageList.new("#{snapshot_loc}")
132
- if (canvas.columns > 640 || canvas.rows > 480)
133
- canvas.resize_to_fill!(640,480)
134
- end
135
-
136
- # create a draw object for annotation
137
- draw = Magick::Draw.new
138
- #if is_mac?
139
- # draw.font = "/Library/Fonts/Impact.ttf"
140
- #else
141
- # draw.font = "/usr/share/fonts/TTF/impact.ttf"
142
- #end
143
- draw.font = File.join(LOLCOMMITS_ROOT, "fonts", "Impact.ttf")
144
-
145
- draw.fill = 'white'
146
- draw.stroke = 'black'
147
-
148
- # convenience method for word wrapping
149
- # based on https://github.com/cmdrkeene/memegen/blob/master/lib/meme_generator.rb
150
- def word_wrap(text, col = 27)
151
- wrapped = text.gsub(/(.{1,#{col + 4}})(\s+|\Z)/, "\\1\n")
152
- wrapped.chomp!
153
- end
154
-
155
- draw.annotate(canvas, 0, 0, 0, 0, commit_sha) do
156
- self.gravity = NorthEastGravity
157
- self.pointsize = 32
158
- self.stroke_width = 2
159
- end
160
-
161
- draw.annotate(canvas, 0, 0, 0, 0, word_wrap(commit_msg)) do
162
- self.gravity = SouthWestGravity
163
- self.pointsize = 48
164
- self.interline_spacing = -(48 / 5) if self.respond_to?(:interline_spacing)
165
- self.stroke_width = 2
166
- end
167
-
168
- #
169
- # Squash the images and write the files
170
- #
171
- #canvas.flatten_images.write("#{loldir}/#{commit_sha}.jpg")
172
- canvas.write(File.join loldir, "#{commit_sha}.jpg")
173
- FileUtils.rm(snapshot_loc)
174
-
175
- #if in test mode, open image for inspection
176
- if is_test
177
- Launchy.open(File.join loldir, "#{commit_sha}.jpg")
178
- end
179
- end
180
- end
3
+ require 'core_ext/class'
4
+ require 'RMagick'
5
+ require 'fileutils'
6
+ require 'git'
7
+ require 'open3'
8
+ require 'active_support/inflector'
9
+ require 'active_support/concern'
10
+ require 'active_support/callbacks'
11
+
12
+ require 'lolcommits/version'
13
+ require 'lolcommits/configuration'
14
+ require 'lolcommits/capturer'
15
+ require 'lolcommits/capture_mac'
16
+ require 'lolcommits/capture_linux'
17
+ require 'lolcommits/capture_windows'
18
+ require 'lolcommits/capture_fake'
19
+ require 'lolcommits/git_info'
20
+ require 'lolcommits/plugin'
21
+ require 'lolcommits/plugins/loltext'
22
+ require 'lolcommits/plugins/dot_com'
23
+ require 'lolcommits/plugins/tranzlate'
24
+
25
+ # require runner after all the plugins have been required
26
+ require 'lolcommits/runner'
@@ -0,0 +1,10 @@
1
+ module Lolcommits
2
+ class CaptureFake < Capturer
3
+ def capture
4
+ test_image = File.join Configuration::LOLCOMMITS_ROOT, "test", "images", "test_image.jpg"
5
+ FileUtils.cp test_image, snapshot_location
6
+ end
7
+
8
+ end
9
+ end
10
+
@@ -0,0 +1,20 @@
1
+ module Lolcommits
2
+ class CaptureLinux < Capturer
3
+ def capture
4
+ tmpdir = File.expand_path "#{Configuration.loldir}/tmpdir#{rand(1000)}/"
5
+ FileUtils.mkdir_p( tmpdir )
6
+ # There's no way to give a capture delay in mplayer, but a number of frame
7
+ # I've found that 6 is a good value for me.
8
+ frames = if capture_delay != 0 then capture_delay else 6 end
9
+
10
+ # mplayer's output is ugly and useless, let's throw it away
11
+ _, r, _ = Open3.popen3("mplayer -vo jpeg:outdir=#{tmpdir} -frames #{frames} tv://")
12
+ # looks like we still need to read the output for something to happen
13
+ r.read
14
+ FileUtils.mv(tmpdir + "/%08d.jpg" % frames, snapshot_location)
15
+ FileUtils.rm_rf( tmpdir )
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,17 @@
1
+ module Lolcommits
2
+ class CaptureMac < Capturer
3
+ def capture_device_string
4
+ @capture_device.nil? ? nil : "-d #{@capture_device}"
5
+ end
6
+
7
+ def capture
8
+ system("#{imagesnap_bin} -q \"#{snapshot_location}\" -w #{capture_delay} #{capture_device_string}")
9
+ end
10
+
11
+ private
12
+
13
+ def imagesnap_bin
14
+ File.join(Configuration::LOLCOMMITS_ROOT, "ext", "imagesnap", "imagesnap")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Lolcommits
2
+ class CaptureWindows < Capturer
3
+ def capture
4
+ commandcam_exe = File.join Configuration::LOLCOMMITS_ROOT, "ext", "CommandCam", "CommandCam.exe"
5
+ # DirectShow takes a while to show... at least for me anyway
6
+ delaycmd = " /delay 3000"
7
+ if capture_delay > 0
8
+ # CommandCam delay is in milliseconds
9
+ delaycmd = " /delay #{capture_delay * 1000}"
10
+ end
11
+ _, r, _ = Open3.popen3("#{commandcam_exe} /filename #{snapshot_location}#{delaycmd}")
12
+ # looks like we still need to read the output for something to happen
13
+ r.read
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,10 @@
1
+ module Lolcommits
2
+ class Capturer
3
+ attr_accessor :capture_device, :capture_delay, :snapshot_location
4
+ def initialize(attributes = Hash.new)
5
+ attributes.each do |attr, val|
6
+ self.send("#{attr}=", val)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,128 @@
1
+ module Lolcommits
2
+ class Configuration
3
+ LOLBASEDIR = ENV['LOLCOMMITS_DIR'] || File.join(ENV['HOME'], '.lolcommits')
4
+ LOLCOMMITS_ROOT = File.join(File.dirname(__FILE__), '../..')
5
+ attr_writer :loldir
6
+
7
+ def initialize(attributes={})
8
+ attributes.each do |attr, val|
9
+ self.send("#{attr}=", val)
10
+ end
11
+ end
12
+
13
+ def self.platform
14
+ if is_fakecapture?
15
+ 'Fake'
16
+ elsif is_mac?
17
+ 'Mac'
18
+ elsif is_linux?
19
+ 'Linux'
20
+ elsif is_windows?
21
+ 'Windows'
22
+ else
23
+ raise "Unknown / Unsupported Platform."
24
+ end
25
+ end
26
+
27
+ def user_configuration
28
+ if File.exists?(user_configuration_file)
29
+ YAML.load(File.open(user_configuration_file))
30
+ else
31
+ nil
32
+ end
33
+ end
34
+
35
+ def user_configuration_file
36
+ "#{self.loldir}/config.yml"
37
+ end
38
+
39
+ def loldir
40
+ return @loldir if @loldir
41
+
42
+ basename ||= File.basename(Git.open('.').dir.to_s).sub(/^\./, 'dot')
43
+ basename.sub!(/ /, '-')
44
+
45
+ @loldir = Configuration.loldir_for(basename)
46
+ end
47
+
48
+ def self.loldir_for(basename)
49
+ loldir = File.join(LOLBASEDIR, basename)
50
+
51
+ if not File.directory? loldir
52
+ FileUtils.mkdir_p loldir
53
+ end
54
+ loldir
55
+ end
56
+
57
+ def most_recent
58
+ Dir.glob(File.join self.loldir, "*").max_by {|f| File.mtime(f)}
59
+ end
60
+
61
+ def raw_image
62
+ File.join self.loldir, "tmp_snapshot.jpg"
63
+ end
64
+
65
+ def main_image(commit_sha)
66
+ File.join self.loldir, "#{commit_sha}.jpg"
67
+ end
68
+
69
+ def puts_plugins
70
+ names = Lolcommits::PLUGINS.collect {|p| p.new(nil).name }
71
+ puts "Available plugins: #{names.join(', ')}"
72
+ end
73
+
74
+ def do_configure!(plugin)
75
+ if plugin.nil? || plugin.strip == ''
76
+ puts_plugins
77
+ print "Name of plugin to configure: "
78
+ plugin = STDIN.gets.strip
79
+ end
80
+
81
+ plugins = Lolcommits::PLUGINS.inject(Hash.new) do |acc, val|
82
+ p = val.new(nil)
83
+ acc.merge(p.name => p)
84
+ end
85
+
86
+ plugin_object = plugins[plugin]
87
+
88
+ if plugin_object.nil?
89
+ puts "Unable to find plugin: #{plugin}"
90
+ return
91
+ end
92
+
93
+ options = plugin_object.options.inject(Hash.new) do |acc, option|
94
+ print "#{option}: "
95
+ val = STDIN.gets.strip
96
+ val = true if val == 'true'
97
+ val = false if val == 'false'
98
+
99
+ acc.merge(option => val)
100
+ end
101
+ config = self.user_configuration || Hash.new
102
+ config[plugin] = options
103
+ File.open(self.user_configuration_file, 'w') do |f|
104
+ f.write(config.to_yaml)
105
+ end
106
+
107
+ puts "#{config.to_yaml}\n"
108
+ puts "Successfully Configured"
109
+ end
110
+
111
+ def self.is_mac?
112
+ RUBY_PLATFORM.downcase.include?("darwin")
113
+ end
114
+
115
+ def self.is_linux?
116
+ RUBY_PLATFORM.downcase.include?("linux")
117
+ end
118
+
119
+ def self.is_windows?
120
+ !! RUBY_PLATFORM.match(/(win|w)32/)
121
+ end
122
+
123
+ def self.is_fakecapture?
124
+ (ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
125
+ end
126
+
127
+ end
128
+ end