lolcommits 0.2.0 → 0.3.0.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.
@@ -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