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
@@ -1,58 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'rest_client'
3
- require 'pp'
4
- require 'json'
5
-
6
- module Lolcommits
7
- class Lolsrv < Plugin
8
- def initialize(runner)
9
- super
10
- options << 'server'
11
- end
12
-
13
- def run_postcapture
14
- return unless valid_configuration?
15
- fork { sync }
16
- end
17
-
18
- def configured?
19
- !configuration['enabled'].nil? && configuration['server']
20
- end
21
-
22
- def sync
23
- existing = existing_lols
24
- return unless existing.nil?
25
- Dir[runner.config.loldir + '/*.{jpg,gif}'].each do |item|
26
- sha = File.basename(item, '.*')
27
- upload(item, sha) unless existing.include?(sha) || sha == 'tmp_snapshot'
28
- end
29
- end
30
-
31
- def existing_lols
32
- lols = JSON.parse(RestClient.get(configuration['server'] + '/lols'))
33
- lols.map { |lol| lol['sha'] }
34
- rescue => e
35
- log_error(e, "ERROR: existing lols could not be retrieved #{e.class} - #{e.message}")
36
- return nil
37
- end
38
-
39
- def upload(file, sha)
40
- RestClient.post(configuration['server'] + '/uplol',
41
- lol: File.new(file),
42
- url: runner.vcs_info.url + sha,
43
- repo: runner.vcs_info.repo,
44
- date: File.ctime(file),
45
- sha: sha)
46
- rescue => e
47
- log_error(e, "ERROR: Upload of lol #{sha} FAILED #{e.class} - #{e.message}")
48
- end
49
-
50
- def self.name
51
- 'lolsrv'
52
- end
53
-
54
- def self.runner_order
55
- :postcapture
56
- end
57
- end
58
- end
@@ -1,184 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module Lolcommits
3
- class Loltext < Plugin
4
- DEFAULT_FONT_PATH = File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'fonts', 'Impact.ttf')
5
-
6
- def self.name
7
- 'loltext'
8
- end
9
-
10
- # enabled by default (if no configuration exists)
11
- def enabled?
12
- !configured? || super
13
- end
14
-
15
- def run_postcapture
16
- debug 'Annotating image via MiniMagick'
17
- image = MiniMagick::Image.open(runner.main_image)
18
- if config_option(:overlay, :enabled)
19
- image.combine_options do |c|
20
- c.fill config_option(:overlay, :overlay_colors).sample
21
- c.colorize config_option(:overlay, :overlay_percent)
22
- end
23
- end
24
-
25
- annotate(image, :message, clean_msg(runner.message))
26
- annotate(image, :sha, runner.sha)
27
- debug "Writing changed file to #{runner.main_image}"
28
- image.write runner.main_image
29
- end
30
-
31
- def annotate(image, type, string)
32
- debug("annotating #{type} to image with #{string}")
33
-
34
- transformed_position = position_transform(config_option(type, :position))
35
- annotate_location = '0'
36
- if transformed_position == 'South'
37
- annotate_location = '+0+20' # Move South gravity off the edge of the image.
38
- end
39
-
40
- string.upcase! if config_option(type, :uppercase)
41
-
42
- image.combine_options do |c|
43
- c.strokewidth runner.capture_animated? ? '1' : '2'
44
- c.interline_spacing(-(config_option(type, :size) / 5))
45
- c.stroke config_option(type, :stroke_color)
46
- c.fill config_option(type, :color)
47
- c.gravity transformed_position
48
- c.pointsize runner.capture_animated? ? (config_option(type, :size) / 2) : config_option(type, :size)
49
- c.font config_option(type, :font)
50
- c.annotate annotate_location, string
51
- end
52
- end
53
-
54
- def configure_options!
55
- options = super
56
- # ask user to configure text options when enabling
57
- if options['enabled']
58
- puts '---------------------------------------------------------------'
59
- puts ' LolText options '
60
- puts ''
61
- puts ' * any blank options will use the (default)'
62
- puts ' * always use the full absolute path to fonts'
63
- puts ' * valid text positions are NE, NW, SE, SW, S, C (centered)'
64
- puts ' * colors can be hex #FC0 value or a string \'white\''
65
- puts ' - use `none` for no stroke color'
66
- puts ' * overlay fills your image with a random color'
67
- puts ' - set one or more overlay_colors with a comma seperator'
68
- puts ' - overlay_percent (0-100) sets the fill colorize strength'
69
- puts '---------------------------------------------------------------'
70
-
71
- options[:message] = configure_sub_options(:message)
72
- options[:sha] = configure_sub_options(:sha)
73
- options[:overlay] = configure_sub_options(:overlay)
74
- end
75
- options
76
- end
77
-
78
- # TODO: consider this type of configuration prompting in the base Plugin
79
- # class, working with hash of defaults
80
- def configure_sub_options(type)
81
- print "#{type}:\n"
82
- defaults = config_defaults[type]
83
-
84
- # sort option keys since different `Hash#keys` varys across Ruby versions
85
- defaults.keys.sort_by(&:to_s).reduce({}) do |acc, opt|
86
- # if we have an enabled key set to false, abort asking for any more options
87
- if acc.key?(:enabled) && acc[:enabled] != true
88
- acc
89
- else
90
- print " #{opt.to_s.tr('_', ' ')} (#{defaults[opt]}): "
91
- val = parse_user_input(STDIN.gets.chomp.strip)
92
- # handle array options (comma seperated string)
93
- if defaults[opt].is_a?(Array) && !val.nil?
94
- val = val.split(',').map(&:strip).delete_if(&:empty?)
95
- end
96
- acc.merge(opt => val)
97
- end
98
- end
99
- end
100
-
101
- def config_defaults
102
- {
103
- message: {
104
- color: 'white',
105
- font: DEFAULT_FONT_PATH,
106
- position: 'SW',
107
- size: 48,
108
- stroke_color: 'black',
109
- uppercase: false
110
- },
111
- sha: {
112
- color: 'white',
113
- font: DEFAULT_FONT_PATH,
114
- position: 'NE',
115
- size: 32,
116
- stroke_color: 'black',
117
- uppercase: false
118
- },
119
- overlay: {
120
- enabled: false,
121
- overlay_colors: [
122
- '#2e4970', '#674685', '#ca242f', '#1e7882', '#2884ae', '#4ba000',
123
- '#187296', '#7e231f', '#017d9f', '#e52d7b', '#0f5eaa', '#e40087',
124
- '#5566ac', '#ed8833', '#f8991c', '#408c93', '#ba9109'
125
- ],
126
- overlay_percent: 50
127
- }
128
- }
129
- end
130
-
131
- def config_option(type, option)
132
- default_option = config_defaults[type][option]
133
- if configuration[type]
134
- configuration[type][option] || default_option
135
- else
136
- default_option
137
- end
138
- end
139
-
140
- private
141
-
142
- # explode psuedo-names for text position
143
- def position_transform(position)
144
- case position
145
- when 'NE'
146
- 'NorthEast'
147
- when 'NW'
148
- 'NorthWest'
149
- when 'SE'
150
- 'SouthEast'
151
- when 'SW'
152
- 'SouthWest'
153
- when 'C'
154
- 'Center'
155
- when 'S'
156
- 'South'
157
- end
158
- end
159
-
160
- # do whatever is required to commit message to get it clean and ready for imagemagick
161
- def clean_msg(text)
162
- wrapped_text = word_wrap text
163
- escape_quotes wrapped_text
164
- escape_ats wrapped_text
165
- end
166
-
167
- # conversion for quotation marks to avoid shell interpretation
168
- # does not seem to be a safe way to escape cross-platform?
169
- def escape_quotes(text)
170
- text.gsub(/"/, "''")
171
- end
172
-
173
- def escape_ats(text)
174
- text.gsub(/@/, '\@')
175
- end
176
-
177
- # convenience method for word wrapping
178
- # based on https://github.com/cmdrkeene/memegen/blob/master/lib/meme_generator.rb
179
- def word_wrap(text, col = 27)
180
- wrapped = text.gsub(/(.{1,#{col + 4}})(\s+|\Z)/, "\\1\n")
181
- wrapped.chomp!
182
- end
183
- end
184
- end
@@ -1,54 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'base64'
3
-
4
- module Lolcommits
5
- class TermOutput < Plugin
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
@@ -1,66 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'rest_client'
3
- require 'base64'
4
-
5
- module Lolcommits
6
- class Uploldz < Plugin
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
- return unless valid_configuration?
23
-
24
- if !runner.vcs_info || runner.vcs_info.repo.empty?
25
- puts 'Repo is empty, skipping upload'
26
- else
27
- debug "Posting capture to #{configuration['endpoint']}"
28
- RestClient.post(
29
- configuration['endpoint'],
30
- {
31
- file: File.new(runner.main_image),
32
- message: runner.message,
33
- repo: runner.vcs_info.repo,
34
- author_name: runner.vcs_info.author_name,
35
- author_email: runner.vcs_info.author_email,
36
- sha: runner.sha,
37
- key: configuration['optional_key']
38
- },
39
- Authorization: authorization_header
40
- )
41
- end
42
- rescue => e
43
- log_error(e, "ERROR: RestClient POST FAILED #{e.class} - #{e.message}")
44
- end
45
-
46
- def configured?
47
- !configuration['enabled'].nil? && configuration['endpoint']
48
- end
49
-
50
- def authorization_header
51
- user = configuration['optional_http_auth_username']
52
- password = configuration['optional_http_auth_password']
53
- return unless user || password
54
-
55
- 'Basic ' + Base64.encode64("#{user}:#{password}").chomp
56
- end
57
-
58
- def self.name
59
- 'uploldz'
60
- end
61
-
62
- def self.runner_order
63
- :postcapture
64
- end
65
- end
66
- end