lolcommits 0.9.2 → 0.9.3.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +6 -0
  3. data/CHANGELOG.md +243 -105
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +10 -3
  6. data/bin/lolcommits +9 -16
  7. data/features/step_definitions/lolcommits_steps.rb +0 -1
  8. data/features/support/env.rb +0 -1
  9. data/features/support/path_helpers.rb +0 -1
  10. data/lib/core_ext/mini_magick/utilities.rb +0 -1
  11. data/lib/lolcommits.rb +16 -16
  12. data/lib/lolcommits/backends/git_info.rb +0 -1
  13. data/lib/lolcommits/backends/installation_git.rb +0 -1
  14. data/lib/lolcommits/backends/installation_mercurial.rb +0 -1
  15. data/lib/lolcommits/backends/mercurial_info.rb +0 -1
  16. data/lib/lolcommits/capturer.rb +0 -1
  17. data/lib/lolcommits/capturer/capture_cygwin.rb +0 -1
  18. data/lib/lolcommits/capturer/capture_fake.rb +0 -1
  19. data/lib/lolcommits/capturer/capture_linux.rb +0 -1
  20. data/lib/lolcommits/capturer/capture_linux_animated.rb +0 -1
  21. data/lib/lolcommits/capturer/capture_mac.rb +0 -1
  22. data/lib/lolcommits/capturer/capture_mac_animated.rb +0 -1
  23. data/lib/lolcommits/capturer/capture_windows.rb +0 -1
  24. data/lib/lolcommits/cli/fatals.rb +0 -8
  25. data/lib/lolcommits/cli/launcher.rb +0 -1
  26. data/lib/lolcommits/cli/process_runner.rb +0 -2
  27. data/lib/lolcommits/cli/timelapse_gif.rb +0 -1
  28. data/lib/lolcommits/configuration.rb +10 -7
  29. data/lib/lolcommits/gem_plugin.rb +46 -0
  30. data/lib/lolcommits/installation.rb +0 -1
  31. data/lib/lolcommits/platform.rb +0 -1
  32. data/lib/lolcommits/plugin/base.rb +110 -0
  33. data/lib/lolcommits/plugin/dot_com.rb +50 -0
  34. data/lib/lolcommits/plugin/lol_flowdock.rb +69 -0
  35. data/lib/lolcommits/plugin/lol_hipchat.rb +124 -0
  36. data/lib/lolcommits/plugin/lol_protonet.rb +68 -0
  37. data/lib/lolcommits/plugin/lol_slack.rb +68 -0
  38. data/lib/lolcommits/plugin/lol_tumblr.rb +129 -0
  39. data/lib/lolcommits/plugin/lol_twitter.rb +176 -0
  40. data/lib/lolcommits/plugin/lol_yammer.rb +84 -0
  41. data/lib/lolcommits/plugin/lolsrv.rb +58 -0
  42. data/lib/lolcommits/plugin/loltext.rb +190 -0
  43. data/lib/lolcommits/plugin/term_output.rb +55 -0
  44. data/lib/lolcommits/{plugins → plugin}/tranzlate.rb +14 -15
  45. data/lib/lolcommits/plugin/uploldz.rb +65 -0
  46. data/lib/lolcommits/plugin_manager.rb +48 -0
  47. data/lib/lolcommits/runner.rb +4 -5
  48. data/lib/lolcommits/test_helpers/fake_io.rb +20 -0
  49. data/lib/lolcommits/test_helpers/git_repo.rb +44 -0
  50. data/lib/lolcommits/vcs_info.rb +0 -1
  51. data/lib/lolcommits/version.rb +2 -2
  52. data/lolcommits.gemspec +2 -2
  53. data/test/lolcommits_test.rb +1 -2
  54. data/test/plugins_test.rb +7 -8
  55. metadata +22 -19
  56. data/lib/core_ext/class.rb +0 -8
  57. data/lib/lolcommits/plugin.rb +0 -123
  58. data/lib/lolcommits/plugins/dot_com.rb +0 -51
  59. data/lib/lolcommits/plugins/lol_flowdock.rb +0 -70
  60. data/lib/lolcommits/plugins/lol_hipchat.rb +0 -125
  61. data/lib/lolcommits/plugins/lol_protonet.rb +0 -69
  62. data/lib/lolcommits/plugins/lol_slack.rb +0 -69
  63. data/lib/lolcommits/plugins/lol_tumblr.rb +0 -129
  64. data/lib/lolcommits/plugins/lol_twitter.rb +0 -176
  65. data/lib/lolcommits/plugins/lol_yammer.rb +0 -85
  66. data/lib/lolcommits/plugins/lolsrv.rb +0 -58
  67. data/lib/lolcommits/plugins/loltext.rb +0 -184
  68. data/lib/lolcommits/plugins/term_output.rb +0 -54
  69. data/lib/lolcommits/plugins/uploldz.rb +0 -66
@@ -0,0 +1,55 @@
1
+ require 'base64'
2
+
3
+ module Lolcommits
4
+ module Plugin
5
+ class TermOutput < Base
6
+ def run_postcapture
7
+ if terminal_supported?
8
+ if !runner.vcs_info || runner.vcs_info.repo.empty?
9
+ debug 'repo is empty, skipping term output'
10
+ else
11
+ base64 = Base64.encode64(open(runner.main_image, &:read))
12
+ puts "#{begin_escape}1337;File=inline=1:#{base64};alt=#{runner.message};#{end_escape}\n"
13
+ end
14
+ else
15
+ debug 'Disabled, your terminal is not supported (requires iTerm2)'
16
+ end
17
+ end
18
+
19
+ def self.name
20
+ 'term_output'
21
+ end
22
+
23
+ def self.runner_order
24
+ :postcapture
25
+ end
26
+
27
+ def configure_options!
28
+ if terminal_supported?
29
+ super
30
+ else
31
+ puts "Sorry, your terminal does not support the #{self.class.name} plugin (requires iTerm2)"
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # escape sequences for tmux sessions differ
38
+ def begin_escape
39
+ tmux? ? "\033Ptmux;\033\033]" : "\033]"
40
+ end
41
+
42
+ def end_escape
43
+ tmux? ? "\a\033\\" : "\a"
44
+ end
45
+
46
+ def tmux?
47
+ !ENV['TMUX'].nil?
48
+ end
49
+
50
+ def terminal_supported?
51
+ ENV['TERM_PROGRAM'] =~ /iTerm/
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,7 +1,4 @@
1
- # -*- encoding : utf-8 -*-
2
1
  # Adapted and expanded from https://github.com/rwtnorton/moar-lolspeak
3
- # which was largely taken from an old Perl script and is sadly is not
4
- # available via rubygems
5
2
 
6
3
  module Lolspeak
7
4
  LOL_DICTIONARY = {
@@ -94,21 +91,23 @@ module Lolspeak
94
91
  end
95
92
 
96
93
  module Lolcommits
97
- class Tranzlate < Plugin
98
- extend Lolspeak
94
+ module Plugin
95
+ class Tranzlate < Base
96
+ extend Lolspeak
99
97
 
100
- def run_precapture
101
- debug "Commit message before: #{runner.message}"
102
- runner.message = self.class.tranzlate(runner.message)
103
- debug "Commit message after: #{runner.message}"
104
- end
98
+ def run_precapture
99
+ debug "Commit message before: #{runner.message}"
100
+ runner.message = self.class.tranzlate(runner.message)
101
+ debug "Commit message after: #{runner.message}"
102
+ end
105
103
 
106
- def self.name
107
- 'tranzlate'
108
- end
104
+ def self.name
105
+ 'tranzlate'
106
+ end
109
107
 
110
- def self.runner_order
111
- :precapture
108
+ def self.runner_order
109
+ :precapture
110
+ end
112
111
  end
113
112
  end
114
113
  end
@@ -0,0 +1,65 @@
1
+ require 'rest_client'
2
+ require 'base64'
3
+
4
+ module Lolcommits
5
+ module Plugin
6
+ class Uploldz < Base
7
+ attr_accessor :endpoint
8
+
9
+ def initialize(runner)
10
+ super
11
+ options.concat(
12
+ %w(
13
+ endpoint
14
+ optional_key
15
+ optional_http_auth_username
16
+ optional_http_auth_password
17
+ )
18
+ )
19
+ end
20
+
21
+ def run_postcapture
22
+ if !runner.vcs_info || runner.vcs_info.repo.empty?
23
+ puts 'Repo is empty, skipping upload'
24
+ else
25
+ debug "Posting capture to #{configuration['endpoint']}"
26
+ RestClient.post(
27
+ configuration['endpoint'],
28
+ {
29
+ file: File.new(runner.main_image),
30
+ message: runner.message,
31
+ repo: runner.vcs_info.repo,
32
+ author_name: runner.vcs_info.author_name,
33
+ author_email: runner.vcs_info.author_email,
34
+ sha: runner.sha,
35
+ key: configuration['optional_key']
36
+ },
37
+ Authorization: authorization_header
38
+ )
39
+ end
40
+ rescue => e
41
+ log_error(e, "ERROR: RestClient POST FAILED #{e.class} - #{e.message}")
42
+ end
43
+
44
+ def configured?
45
+ !configuration['enabled'].nil? && configuration['endpoint']
46
+ end
47
+
48
+ def authorization_header
49
+ user = configuration['optional_http_auth_username']
50
+ password = configuration['optional_http_auth_password']
51
+ return unless user || password
52
+
53
+ 'Basic ' + Base64.encode64("#{user}:#{password}").chomp
54
+ end
55
+
56
+ def self.name
57
+ 'uploldz'
58
+ end
59
+
60
+ def self.runner_order
61
+ :postcapture
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,48 @@
1
+ module Lolcommits
2
+ class PluginManager
3
+ GEM_NAME_PREFIX = /^lolcommits-plugin-/
4
+
5
+ def initialize
6
+ @plugins = []
7
+ end
8
+
9
+ # @return [Array] find all installed and supported plugins, storing to
10
+ # @plugins Array, and returns this array
11
+ def locate_plugins
12
+ gem_list.each do |gem|
13
+ next if gem.name !~ GEM_NAME_PREFIX
14
+ plugin_name = gem.name.split('-', 2).last
15
+ plugin = GemPlugin.new(plugin_name, gem.name, gem)
16
+
17
+ @plugins << plugin if plugin.supported? && !plugin_located?(plugin)
18
+ end
19
+ @plugins
20
+ end
21
+
22
+ # @return [Hash] A hash with all plugin names (minus the prefix) as
23
+ # keys and Plugin objects as values
24
+ def plugins
25
+ h = {}
26
+ @plugins.each do |plugin|
27
+ h[plugin.name] = plugin
28
+ end
29
+ h
30
+ end
31
+
32
+ # require all plugins
33
+ def load_plugins
34
+ @plugins.map(&:activate!)
35
+ end
36
+
37
+ private
38
+
39
+ def plugin_located?(plugin)
40
+ @plugins.any? { |existing| existing.gem_name == plugin.gem_name }
41
+ end
42
+
43
+ def gem_list
44
+ Gem.refresh
45
+ Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'lolcommits/platform'
3
2
 
4
3
  module Lolcommits
@@ -33,7 +32,6 @@ module Lolcommits
33
32
 
34
33
  # do native plugins that need to happen before capture
35
34
  plugins_for(:precapture).each do |plugin|
36
- debug "Runner: precapture about to execute #{plugin}"
37
35
  plugin.new(self).execute_precapture
38
36
  end
39
37
 
@@ -51,11 +49,10 @@ module Lolcommits
51
49
  # do native plugins that need to happen immediately after capture and
52
50
  # resize this is effectively the "image processing" phase for now,
53
51
  # reserve just for us and handle manually...?
54
- Lolcommits::Loltext.new(self).execute_postcapture
52
+ Lolcommits::Plugin::Loltext.new(self).execute_postcapture
55
53
 
56
54
  # do native plugins that need to happen after capture
57
55
  plugins_for(:postcapture).each do |plugin|
58
- debug "Runner: postcapture about to execute #{plugin}"
59
56
  plugin.new(self).execute_postcapture
60
57
  end
61
58
 
@@ -69,12 +66,14 @@ module Lolcommits
69
66
  end
70
67
  end
71
68
 
69
+ # TODO: - move these plugin methods to Lolcommits::PluginManager after all
70
+ # plugins get "gemified"
72
71
  def plugins_for(position)
73
72
  self.class.plugins.select { |p| p.runner_order == position }
74
73
  end
75
74
 
76
75
  def self.plugins
77
- Lolcommits::Plugin.subclasses
76
+ Lolcommits::Plugin.constants.map(&Lolcommits::Plugin.method(:const_get)) - [Lolcommits::Plugin::Base]
78
77
  end
79
78
 
80
79
  # the main capture
@@ -0,0 +1,20 @@
1
+ module Lolcommits
2
+ module TestHelpers
3
+ module FakeIO
4
+ # stdout captured and returned
5
+ # stdin mapped to inputs an IO stream seperated with enter key presses
6
+ def fake_io_capture(inputs: [])
7
+ input_stream = "#{inputs.join("\r\n")}\r\n"
8
+ $stdin = StringIO.new(input_stream)
9
+ $stdout = StringIO.new
10
+
11
+ yield
12
+
13
+ $stdout.string
14
+ ensure
15
+ $stdin = STDIN
16
+ $stdout = STDOUT
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ module Lolcommits
2
+ module TestHelpers
3
+ module GitRepo
4
+ def repo
5
+ @repo ||= Git.open(repo_path)
6
+ end
7
+
8
+ def repo_path
9
+ '~/.lolcommits/sample-plugin-test-repo'
10
+ end
11
+
12
+ def repo_exists?
13
+ File.directory?(File.expand_path(repo_path, '.git'))
14
+ end
15
+
16
+ def last_commit
17
+ repo.log.first
18
+ end
19
+
20
+ def setup_repo
21
+ return if repo_exists?
22
+ `git init --quiet #{repo_path}`
23
+ end
24
+
25
+ def commit_repo_with_message(message = 'test message', file_name: 'test.txt', file_content: 'testing')
26
+ setup_repo unless repo_exists?
27
+ `echo '#{file_content}' >> #{repo_path}/#{file_name}`
28
+ `cd #{repo_path} && git add #{file_name}`
29
+ `cd #{repo_path} && git commit -m "#{message}"`
30
+ end
31
+
32
+ def in_repo
33
+ return unless repo_exists?
34
+ Dir.chdir(File.expand_path(repo_path)) do
35
+ yield
36
+ end
37
+ end
38
+
39
+ def teardown_repo
40
+ `rm -rf #{repo_path}`
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  module Lolcommits
3
2
  # base class ala plugin.rb
4
3
  class VCSInfo
@@ -1,4 +1,4 @@
1
- # -*- encoding : utf-8 -*-
2
1
  module Lolcommits
3
- VERSION = '0.9.2'.freeze
2
+ VERSION = '0.9.3.pre1'.freeze
3
+ GEM_NAME = 'lolcommits'.freeze
4
4
  end
data/lolcommits.gemspec CHANGED
@@ -1,11 +1,11 @@
1
- # -*- encoding: utf-8 -*-
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'lolcommits/version'
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = 'lolcommits'
6
+ s.name = Lolcommits::GEM_NAME.dup
8
7
  s.version = Lolcommits::VERSION.dup
8
+
9
9
  s.authors = ['Matthew Rothenberg', 'Matthew Hutchinson']
10
10
  s.email = ['mrothenberg@gmail.com', 'matt@hiddenloop.com']
11
11
  s.homepage = 'http://mroth.github.com/lolcommits/'
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'coveralls'
3
2
  Coveralls.wear!
4
3
 
@@ -19,7 +18,7 @@ class LolTest < MiniTest::Test
19
18
  # this will test the permissions but only locally, important before building a gem package!
20
19
  #
21
20
  def test_permissions
22
- impact_perms = File.lstat(Lolcommits::Loltext::DEFAULT_FONT_PATH).mode & 0o777
21
+ impact_perms = File.lstat(Lolcommits::Plugin::Loltext::DEFAULT_FONT_PATH).mode & 0o777
23
22
  imagesnap_perms = File.lstat(File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', 'imagesnap', 'imagesnap')).mode & 0o777
24
23
  videosnap_perms = File.lstat(File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', 'videosnap', 'videosnap')).mode & 0o777
25
24
  commandcam_perms = File.lstat(File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', 'CommandCam', 'CommandCam.exe')).mode & 0o777
data/test/plugins_test.rb CHANGED
@@ -1,4 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
1
  require 'coveralls'
3
2
  Coveralls.wear!
4
3
 
@@ -19,7 +18,7 @@ class PluginsTest < MiniTest::Test
19
18
  #
20
19
  def test_tranzlate
21
20
  [['what the hell', '(WH|W)UT TEH HELL'], ['seriously wtf', 'SRSLEH WTF']].each do |normal, lol|
22
- tranzlated = Lolcommits::Tranzlate.tranzlate(normal)
21
+ tranzlated = Lolcommits::Plugin::Tranzlate.tranzlate(normal)
23
22
  assert_match(/^#{lol}/, tranzlated)
24
23
  end
25
24
  end
@@ -28,25 +27,25 @@ class PluginsTest < MiniTest::Test
28
27
  # issue #136, https://github.com/mroth/lolcommits/issues/136
29
28
  def test_lol_twitter_build_tweet
30
29
  long_commit_message = FFaker::Lorem.sentence(500)
31
- plugin = Lolcommits::LolTwitter.new(nil)
30
+ plugin = Lolcommits::Plugin::LolTwitter.new(nil)
32
31
  max_tweet_size = 116
33
32
  suffix = '... #lolcommits'
34
33
 
35
- Lolcommits::LolTwitter.send(:define_method, :max_tweet_size, proc { max_tweet_size })
36
- Lolcommits::LolTwitter.send(:define_method, :configuration, proc { {} })
34
+ Lolcommits::Plugin::LolTwitter.send(:define_method, :max_tweet_size, proc { max_tweet_size })
35
+ Lolcommits::Plugin::LolTwitter.send(:define_method, :configuration, proc { {} })
37
36
  assert_equal "#{long_commit_message[0..(max_tweet_size - suffix.length)]}#{suffix}", plugin.build_tweet(long_commit_message)
38
37
  end
39
38
 
40
39
  def test_lol_twitter_prefix_suffix
41
- plugin = Lolcommits::LolTwitter.new(nil)
42
- Lolcommits::LolTwitter.send(:define_method, :max_tweet_size, proc { 116 })
40
+ plugin = Lolcommits::Plugin::LolTwitter.new(nil)
41
+ Lolcommits::Plugin::LolTwitter.send(:define_method, :max_tweet_size, proc { 116 })
43
42
  assert_match 'commit msg #lolcommits', plugin.build_tweet('commit msg')
44
43
 
45
44
  plugin_config = {
46
45
  'prefix' => '@prefixing!',
47
46
  'suffix' => '#suffixing!'
48
47
  }
49
- Lolcommits::LolTwitter.send(:define_method, :configuration, proc { plugin_config })
48
+ Lolcommits::Plugin::LolTwitter.send(:define_method, :configuration, proc { plugin_config })
50
49
  assert_equal '@prefixing! commit msg #suffixing!', plugin.build_tweet('commit msg')
51
50
  end
52
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lolcommits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Rothenberg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-01-04 00:00:00.000000000 Z
12
+ date: 2017-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aruba
@@ -327,7 +327,6 @@ files:
327
327
  - features/step_definitions/lolcommits_steps.rb
328
328
  - features/support/env.rb
329
329
  - features/support/path_helpers.rb
330
- - lib/core_ext/class.rb
331
330
  - lib/core_ext/mercurial-ruby/command.rb
332
331
  - lib/core_ext/mercurial-ruby/shell.rb
333
332
  - lib/core_ext/mini_magick/utilities.rb
@@ -350,23 +349,27 @@ files:
350
349
  - lib/lolcommits/cli/process_runner.rb
351
350
  - lib/lolcommits/cli/timelapse_gif.rb
352
351
  - lib/lolcommits/configuration.rb
352
+ - lib/lolcommits/gem_plugin.rb
353
353
  - lib/lolcommits/installation.rb
354
354
  - lib/lolcommits/platform.rb
355
- - lib/lolcommits/plugin.rb
356
- - lib/lolcommits/plugins/dot_com.rb
357
- - lib/lolcommits/plugins/lol_flowdock.rb
358
- - lib/lolcommits/plugins/lol_hipchat.rb
359
- - lib/lolcommits/plugins/lol_protonet.rb
360
- - lib/lolcommits/plugins/lol_slack.rb
361
- - lib/lolcommits/plugins/lol_tumblr.rb
362
- - lib/lolcommits/plugins/lol_twitter.rb
363
- - lib/lolcommits/plugins/lol_yammer.rb
364
- - lib/lolcommits/plugins/lolsrv.rb
365
- - lib/lolcommits/plugins/loltext.rb
366
- - lib/lolcommits/plugins/term_output.rb
367
- - lib/lolcommits/plugins/tranzlate.rb
368
- - lib/lolcommits/plugins/uploldz.rb
355
+ - lib/lolcommits/plugin/base.rb
356
+ - lib/lolcommits/plugin/dot_com.rb
357
+ - lib/lolcommits/plugin/lol_flowdock.rb
358
+ - lib/lolcommits/plugin/lol_hipchat.rb
359
+ - lib/lolcommits/plugin/lol_protonet.rb
360
+ - lib/lolcommits/plugin/lol_slack.rb
361
+ - lib/lolcommits/plugin/lol_tumblr.rb
362
+ - lib/lolcommits/plugin/lol_twitter.rb
363
+ - lib/lolcommits/plugin/lol_yammer.rb
364
+ - lib/lolcommits/plugin/lolsrv.rb
365
+ - lib/lolcommits/plugin/loltext.rb
366
+ - lib/lolcommits/plugin/term_output.rb
367
+ - lib/lolcommits/plugin/tranzlate.rb
368
+ - lib/lolcommits/plugin/uploldz.rb
369
+ - lib/lolcommits/plugin_manager.rb
369
370
  - lib/lolcommits/runner.rb
371
+ - lib/lolcommits/test_helpers/fake_io.rb
372
+ - lib/lolcommits/test_helpers/git_repo.rb
370
373
  - lib/lolcommits/vcs_info.rb
371
374
  - lib/lolcommits/version.rb
372
375
  - lolcommits.gemspec
@@ -395,9 +398,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
395
398
  version: '2.0'
396
399
  required_rubygems_version: !ruby/object:Gem::Requirement
397
400
  requirements:
398
- - - ">="
401
+ - - ">"
399
402
  - !ruby/object:Gem::Version
400
- version: '0'
403
+ version: 1.3.1
401
404
  requirements:
402
405
  - imagemagick
403
406
  - a webcam