lolcommits 0.9.8 → 0.10.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +47 -36
- data/.travis.yml +3 -3
- data/CHANGELOG.md +12 -1
- data/README.md +2 -9
- data/appveyor.yml +0 -4
- data/features/bugs.feature +0 -10
- data/features/lolcommits.feature +12 -11
- data/features/step_definitions/lolcommits_steps.rb +2 -1
- data/features/support/path_helpers.rb +1 -3
- data/lib/core_ext/hash/hash_dig.rb +21 -0
- data/lib/lolcommits.rb +2 -0
- data/lib/lolcommits/backends/git_info.rb +6 -8
- data/lib/lolcommits/configuration.rb +49 -29
- data/lib/lolcommits/gem_plugin.rb +10 -1
- data/lib/lolcommits/plugin/base.rb +73 -66
- data/lib/lolcommits/plugin/configuration_helper.rb +51 -0
- data/lib/lolcommits/plugin_manager.rb +8 -13
- data/lib/lolcommits/runner.rb +18 -9
- data/lib/lolcommits/version.rb +1 -1
- data/lolcommits.gemspec +1 -2
- data/test/lolcommits_test.rb +3 -3
- metadata +16 -22
- data/features/plugins.feature +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ac258b4768122ade54206ac494b52d041dbe1ddbee4a8f464d302c4e477805c
|
4
|
+
data.tar.gz: 91abb44e9340561efb31942349d2b8edc17ad3b1d86149fe25bdae394beca967
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a6946be8f2501f30dc74da7ffb99f332222f5489be04cb8be41c4c62112a7a82eb30de5f342f57219cf172413ed7df73405eab044be19ee15b8edb71a25b816
|
7
|
+
data.tar.gz: db2a6f1e5446ab3ed915d6229e91e97f28a359557d88b7f9a83b27d1516d562d0a40f266a4c40ef938e7f5843646a09391ea3fd2414577a2e0ec8748a18a96d7
|
data/.rubocop.yml
CHANGED
@@ -8,4 +8,12 @@ Metrics/BlockLength:
|
|
8
8
|
Exclude:
|
9
9
|
- 'lolcommits.gemspec'
|
10
10
|
|
11
|
+
# don't agree with this one, can lead to long lines that are harder to parse
|
12
|
+
Style/IfUnlessModifier:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
# our gem supports 2.0+ but Rubocop only supports 2.1+
|
16
|
+
Gemspec/RequiredRubyVersion:
|
17
|
+
Enabled: false
|
18
|
+
|
11
19
|
inherit_from: .rubocop_todo.yml
|
data/.rubocop_todo.yml
CHANGED
@@ -1,44 +1,54 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-
|
3
|
+
# on 2017-12-13 17:09:06 +0000 using RuboCop version 0.52.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
+
# Offense count: 7
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
# Configuration parameters: Include, TreatCommentsAsGroupSeparators.
|
12
|
+
# Include: **/*.gemspec
|
13
|
+
Gemspec/OrderedDependencies:
|
14
|
+
Exclude:
|
15
|
+
- 'lolcommits.gemspec'
|
16
|
+
|
17
|
+
# Offense count: 1
|
18
|
+
# Cop supports --auto-correct.
|
19
|
+
# Configuration parameters: EnforcedStyle.
|
20
|
+
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
|
21
|
+
Layout/IndentHeredoc:
|
22
|
+
Exclude:
|
23
|
+
- 'lib/lolcommits/backends/installation_git.rb'
|
24
|
+
|
9
25
|
# Offense count: 1
|
10
26
|
Lint/AmbiguousBlockAssociation:
|
11
27
|
Exclude:
|
12
28
|
- 'lib/lolcommits/cli/process_runner.rb'
|
13
29
|
|
14
|
-
# Offense count:
|
30
|
+
# Offense count: 19
|
15
31
|
Metrics/AbcSize:
|
16
|
-
Max:
|
32
|
+
Max: 35
|
17
33
|
|
18
|
-
# Offense count:
|
34
|
+
# Offense count: 1
|
19
35
|
# Configuration parameters: CountComments, ExcludedMethods.
|
20
36
|
Metrics/BlockLength:
|
21
|
-
Max:
|
37
|
+
Max: 40
|
22
38
|
|
23
|
-
# Offense count:
|
39
|
+
# Offense count: 2
|
24
40
|
# Configuration parameters: CountComments.
|
25
41
|
Metrics/ClassLength:
|
26
|
-
Max:
|
42
|
+
Max: 140
|
27
43
|
|
28
|
-
# Offense count:
|
44
|
+
# Offense count: 5
|
29
45
|
Metrics/CyclomaticComplexity:
|
30
46
|
Max: 9
|
31
47
|
|
32
|
-
# Offense count:
|
33
|
-
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
34
|
-
# URISchemes: http, https
|
35
|
-
Metrics/LineLength:
|
36
|
-
Max: 161
|
37
|
-
|
38
|
-
# Offense count: 42
|
48
|
+
# Offense count: 23
|
39
49
|
# Configuration parameters: CountComments.
|
40
50
|
Metrics/MethodLength:
|
41
|
-
Max:
|
51
|
+
Max: 24
|
42
52
|
|
43
53
|
# Offense count: 5
|
44
54
|
Metrics/PerceivedComplexity:
|
@@ -50,37 +60,38 @@ Security/YAMLLoad:
|
|
50
60
|
Exclude:
|
51
61
|
- 'lib/lolcommits/configuration.rb'
|
52
62
|
|
53
|
-
# Offense count:
|
63
|
+
# Offense count: 25
|
54
64
|
Style/Documentation:
|
55
65
|
Enabled: false
|
56
66
|
|
57
|
-
# Offense count:
|
58
|
-
|
59
|
-
Layout/EmptyLinesAroundBeginBody:
|
60
|
-
Exclude:
|
61
|
-
- 'lib/lolcommits/plugin/lol_flowdock.rb'
|
62
|
-
- 'lib/lolcommits/plugin/lol_slack.rb'
|
63
|
-
|
64
|
-
# Offense count: 1
|
65
|
-
# Cop supports --auto-correct.
|
66
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
67
|
-
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
|
68
|
-
Layout/IndentHeredoc:
|
67
|
+
# Offense count: 5
|
68
|
+
Style/MixinUsage:
|
69
69
|
Exclude:
|
70
|
-
- '
|
70
|
+
- 'Rakefile'
|
71
|
+
- 'bin/lolcommits'
|
72
|
+
- 'features/support/env.rb'
|
73
|
+
- 'test/lolcommits_test.rb'
|
71
74
|
|
72
|
-
# Offense count:
|
75
|
+
# Offense count: 5
|
73
76
|
# Cop supports --auto-correct.
|
74
77
|
# Configuration parameters: PreferredDelimiters.
|
75
78
|
Style/PercentLiteralDelimiters:
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
79
|
+
Exclude:
|
80
|
+
- 'Rakefile'
|
81
|
+
- 'features/support/path_helpers.rb'
|
82
|
+
- 'lib/lolcommits/backends/installation_mercurial.rb'
|
83
|
+
- 'lib/lolcommits/cli/fatals.rb'
|
84
|
+
- 'lib/lolcommits/installation.rb'
|
80
85
|
|
81
86
|
# Offense count: 1
|
82
87
|
# Cop supports --auto-correct.
|
83
|
-
# Configuration parameters:
|
88
|
+
# Configuration parameters: MinSize.
|
84
89
|
# SupportedStyles: percent, brackets
|
85
90
|
Style/SymbolArray:
|
86
91
|
EnforcedStyle: brackets
|
92
|
+
|
93
|
+
# Offense count: 90
|
94
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
95
|
+
# URISchemes: http, https
|
96
|
+
Metrics/LineLength:
|
97
|
+
Max: 161
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,14 @@ project adheres to [Semantic Versioning][Semver].
|
|
7
7
|
|
8
8
|
* Your contribution here!
|
9
9
|
|
10
|
+
## [0.10.0][] (10 January 2018)
|
11
|
+
* Plugin configuration changes (@matthutchinson [#365][])
|
12
|
+
- `--plugins` now shows if plugin is enabled or not
|
13
|
+
- `default_options` now available, nested hash with default values
|
14
|
+
- if `valid_configuration?` fails, warning message shows
|
15
|
+
- `prompt_autocomplete_hash` helper method added
|
16
|
+
* Better plugin config flow (@matthutchinson [#363][])
|
17
|
+
|
10
18
|
## [0.9.8][] (3 December 2017)
|
11
19
|
* Extract protonet to gem (@matthutchinson [#361][])
|
12
20
|
* Extract flowdock to gem (@matthutchinson [#360][])
|
@@ -302,7 +310,8 @@ project adheres to [Semantic Versioning][Semver].
|
|
302
310
|
instead of compositing multiply image Caption objects (this seems to be more
|
303
311
|
reliable to not glitch.)
|
304
312
|
|
305
|
-
[Unreleased]: https://github.com/mroth/lolcommits/compare/v0.
|
313
|
+
[Unreleased]: https://github.com/mroth/lolcommits/compare/v0.10.0...HEAD
|
314
|
+
[0.10.0]: https://github.com/mroth/lolcommits/compare/v0.9.8...v0.10.0
|
306
315
|
[0.9.8]: https://github.com/mroth/lolcommits/compare/v0.9.7...v0.9.8
|
307
316
|
[0.9.7]: https://github.com/mroth/lolcommits/compare/v0.9.6...v0.9.7
|
308
317
|
[0.9.6]: https://github.com/mroth/lolcommits/compare/v0.9.5...v0.9.6
|
@@ -484,3 +493,5 @@ project adheres to [Semantic Versioning][Semver].
|
|
484
493
|
[#359]: https://github.com/mroth/lolcommits/pull/359
|
485
494
|
[#360]: https://github.com/mroth/lolcommits/pull/360
|
486
495
|
[#361]: https://github.com/mroth/lolcommits/pull/361
|
496
|
+
[#363]: https://github.com/mroth/lolcommits/pull/363
|
497
|
+
[#365]: https://github.com/mroth/lolcommits/pull/365
|
data/README.md
CHANGED
@@ -190,13 +190,6 @@ other services), or even translate your commit messages to
|
|
190
190
|
out on our [plugins
|
191
191
|
page](https://github.com/mroth/lolcommits/wiki/Configuring-Plugins).
|
192
192
|
|
193
|
-
Until recently, all plugins lived inside the main lolcommits gem. We are in the
|
194
|
-
process of extracting them to individual gems. For [gem
|
195
|
-
plugins](https://github.com/search?q=topic%3Alolcommits-plugin+org%3Alolcommits&type=Repositories),
|
196
|
-
you'll need to install the gem first:
|
197
|
-
|
198
|
-
[sudo] gem install lolcommits-plugin-sample
|
199
|
-
|
200
193
|
To list all installed plugins use:
|
201
194
|
|
202
195
|
lolcommits --plugins
|
@@ -209,8 +202,8 @@ Installed plugins can be easily enabled, configured or disabled with the
|
|
209
202
|
lolcommits --config -p loltext
|
210
203
|
|
211
204
|
Interested in developing your own plugin? Follow [this simple
|
212
|
-
guide](https://github.com/lolcommits/lolcommits-
|
213
|
-
Lolcommits Plugin
|
205
|
+
guide](https://github.com/lolcommits/lolcommits-sample_plugin#developing-your-own-plugin) at the
|
206
|
+
Lolcommits Sample Plugin README.
|
214
207
|
|
215
208
|
|
216
209
|
## Timelapse
|
data/appveyor.yml
CHANGED
data/features/bugs.feature
CHANGED
@@ -26,16 +26,6 @@ Feature: Bug regression testing
|
|
26
26
|
# Then there should be 4 commit entries in the git log
|
27
27
|
Then there should be exactly 6 jpgs in "../.lolcommits/yuh8history"
|
28
28
|
|
29
|
-
#
|
30
|
-
# issue #81, https://github.com/mroth/lolcommits/issues/81
|
31
|
-
#
|
32
|
-
Scenario: don't want initialized constant warning from Faraday (MRI 1.8.7)
|
33
|
-
When I successfully run `lolcommits`
|
34
|
-
Then the output should not contain:
|
35
|
-
"""
|
36
|
-
warning: already initialized constant DEFAULT_BOUNDARY
|
37
|
-
"""
|
38
|
-
|
39
29
|
#
|
40
30
|
# issue #87, https://github.com/mroth/lolcommits/issues/87
|
41
31
|
#
|
data/features/lolcommits.feature
CHANGED
@@ -67,15 +67,16 @@ Feature: Basic UI functionality
|
|
67
67
|
"""
|
68
68
|
And the exit status should be 1
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
70
|
+
# flakey test sometimes fails: https://travis-ci.org/mroth/lolcommits/jobs/312629988#L620
|
71
|
+
# Scenario: Capture doesnt break in forked mode
|
72
|
+
# Given I am in a git repo named "forked"
|
73
|
+
# And I do a git commit
|
74
|
+
# When I run `lolcommits --capture --fork`
|
75
|
+
# Then there should be exactly 1 pid in "~/.lolcommits/forked"
|
76
|
+
# When I wait for the child process to exit in "forked"
|
77
|
+
# Then a directory named "~/.lolcommits/forked" should exist
|
78
|
+
# And a file named "~/.lolcommits/forked/tmp_snapshot.jpg" should not exist
|
79
|
+
# And there should be exactly 1 jpg in "~/.lolcommits/forked"
|
79
80
|
|
80
81
|
Scenario: Commiting in an enabled git repo triggers successful capture
|
81
82
|
Given I am in a git repo named "myrepo" with lolcommits enabled
|
@@ -119,10 +120,10 @@ Feature: Basic UI functionality
|
|
119
120
|
When I run `lolcommits --config --test -p loltext` interactively
|
120
121
|
And I wait for output to contain "enabled:"
|
121
122
|
Then I type "false"
|
122
|
-
|
123
|
+
Then the output should contain "Disabling plugin: loltext - answer with 'true' to enable & configure"
|
123
124
|
And a file named "~/.lolcommits/test/config.yml" should exist
|
124
125
|
When I successfully run `lolcommits --test --show-config`
|
125
|
-
Then the output should match /loltext:\s
|
126
|
+
Then the output should match /loltext:\s+:enabled: false/
|
126
127
|
|
127
128
|
Scenario: test capture should work regardless of whether in a lolrepo
|
128
129
|
Given I am in a directory named "nothingtoseehere"
|
@@ -160,7 +160,8 @@ Then(/^there should be exactly (.*?) (jpg|gif|pid)s? in "(.*?)"$/) do |n, type,
|
|
160
160
|
end
|
161
161
|
|
162
162
|
Then(/^the output should contain a list of plugins$/) do
|
163
|
-
step %(the output should contain "
|
163
|
+
step %(the output should contain "Installed plugins: (* enabled)")
|
164
|
+
step %(the output should contain "[*] loltext")
|
164
165
|
end
|
165
166
|
|
166
167
|
When(/^I do a git commit with commit message "(.*?)"$/) do |commit_msg|
|
@@ -30,9 +30,7 @@ module PathHelpers
|
|
30
30
|
def preseve_cmds_in_path(cmds, tmpbindir)
|
31
31
|
cmds.each do |cmd|
|
32
32
|
whichcmd = Lolcommits::Platform.command_which(cmd)
|
33
|
-
unless whichcmd.nil?
|
34
|
-
FileUtils.ln_s whichcmd, File.join(tmpbindir, File.basename(whichcmd))
|
35
|
-
end
|
33
|
+
FileUtils.ln_s whichcmd, File.join(tmpbindir, File.basename(whichcmd)) unless whichcmd.nil?
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Backport Hash#dig to Ruby < 2.3
|
2
|
+
# inspired by https://github.com/Invoca/ruby_dig
|
3
|
+
|
4
|
+
module HashDig
|
5
|
+
def dig(key, *rest)
|
6
|
+
value = self[key]
|
7
|
+
if value.nil? || rest.empty?
|
8
|
+
value
|
9
|
+
elsif value.respond_to?(:dig)
|
10
|
+
value.dig(*rest)
|
11
|
+
else
|
12
|
+
raise TypeError, "#{value.class} does not have #dig method"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if RUBY_VERSION < '2.3'
|
18
|
+
class Hash
|
19
|
+
include HashDig
|
20
|
+
end
|
21
|
+
end
|
data/lib/lolcommits.rb
CHANGED
@@ -42,18 +42,12 @@ module Lolcommits
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def url
|
45
|
-
@url ||=
|
46
|
-
if repository.remote && repository.remote.url
|
47
|
-
remote_https_url(repository.remote.url)
|
48
|
-
end
|
49
|
-
end
|
45
|
+
@url ||= remote_repo? ? remote_https_url(repository.remote.url) : nil
|
50
46
|
end
|
51
47
|
|
52
48
|
def repo
|
53
49
|
@repo ||= begin
|
54
|
-
|
55
|
-
match = repository.remote.url.match(GIT_URL_REGEX)
|
56
|
-
end
|
50
|
+
match = repository.remote.url.match(GIT_URL_REGEX) if remote_repo?
|
57
51
|
|
58
52
|
if match
|
59
53
|
match[1]
|
@@ -88,5 +82,9 @@ module Lolcommits
|
|
88
82
|
def last_commit
|
89
83
|
@commit ||= repository.log.first
|
90
84
|
end
|
85
|
+
|
86
|
+
def remote_repo?
|
87
|
+
repository.remote && repository.remote.url
|
88
|
+
end
|
91
89
|
end
|
92
90
|
end
|
@@ -11,11 +11,13 @@ module Lolcommits
|
|
11
11
|
@loldir = Configuration.loldir_for('test') if test_mode
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def yaml
|
15
|
+
@_yaml ||= begin
|
16
|
+
return Hash.new({}) unless File.exist?(configuration_file)
|
17
|
+
# TODO: change to safe_load when Ruby 2.0.0 support drops
|
18
|
+
# YAML.safe_load(File.open(configuration_file), [Symbol])
|
19
|
+
YAML.load(File.open(configuration_file)) || Hash.new({})
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
23
|
def configuration_file
|
@@ -65,19 +67,23 @@ module Lolcommits
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def list_plugins
|
68
|
-
puts "
|
70
|
+
puts "Installed plugins: (* enabled)\n"
|
71
|
+
|
72
|
+
plugin_manager.plugins.each do |gem_plugin|
|
73
|
+
plugin = gem_plugin.plugin_klass.new(config: yaml[gem_plugin.name])
|
74
|
+
puts " [#{plugin.enabled? ? '*' : '-'}] #{gem_plugin.name}"
|
75
|
+
end
|
69
76
|
end
|
70
77
|
|
71
|
-
def find_plugin(
|
72
|
-
plugin_name =
|
73
|
-
|
78
|
+
def find_plugin(name)
|
79
|
+
plugin_name = name.empty? ? ask_for_plugin_name : name
|
80
|
+
plugin = plugin_manager.find_by_name(plugin_name)
|
74
81
|
|
75
|
-
|
76
|
-
return plugin_klass.new(config: self) if plugin_klass
|
82
|
+
return plugin if plugin
|
77
83
|
|
78
84
|
puts "Unable to find plugin: '#{plugin_name}'"
|
79
|
-
|
80
|
-
|
85
|
+
list_plugins unless name.empty?
|
86
|
+
nil
|
81
87
|
end
|
82
88
|
|
83
89
|
def ask_for_plugin_name
|
@@ -88,33 +94,47 @@ module Lolcommits
|
|
88
94
|
|
89
95
|
def do_configure!(plugin_name)
|
90
96
|
$stdout.sync = true
|
91
|
-
|
92
97
|
plugin = find_plugin(plugin_name.to_s.strip)
|
93
98
|
return unless plugin
|
94
|
-
|
95
|
-
|
96
|
-
plugin_config = plugin.configure_options!
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
puts "
|
99
|
+
|
100
|
+
puts "Configuring plugin: #{plugin.name}\n"
|
101
|
+
plugin_config = plugin.plugin_klass.new(config: yaml[plugin_name]).configure_options! || {}
|
102
|
+
|
103
|
+
unless plugin_config[:enabled]
|
104
|
+
puts "Disabling plugin: #{plugin.name} - answer with 'true' to enable & configure"
|
105
|
+
end
|
106
|
+
rescue Interrupt
|
107
|
+
# e.g. user Ctrl+c or aborted by plugin configure_options!
|
108
|
+
puts "\n"
|
109
|
+
if plugin
|
110
|
+
puts "Configuration aborted: #{plugin.name} has been disabled"
|
111
|
+
plugin_config ||= {}
|
112
|
+
plugin_config[:enabled] = false
|
113
|
+
end
|
114
|
+
ensure
|
115
|
+
if plugin
|
116
|
+
# clean away legacy enabled key, later we can remove this
|
117
|
+
plugin_config.delete('enabled')
|
118
|
+
# save plugin config (if we have anything in the hash)
|
119
|
+
save(plugin.name, plugin_config) unless plugin_config.empty?
|
120
|
+
|
121
|
+
# print config if plugin was enabled
|
122
|
+
if plugin_config[:enabled]
|
123
|
+
puts "\nSuccessfully configured plugin: #{plugin.name} - at path '#{configuration_file}'"
|
124
|
+
puts plugin_config.to_yaml.to_s
|
125
|
+
end
|
106
126
|
end
|
107
127
|
end
|
108
128
|
|
109
|
-
def save(
|
110
|
-
config_file_contents =
|
129
|
+
def save(plugin_name, plugin_config)
|
130
|
+
config_file_contents = yaml.merge(plugin_name => plugin_config).to_yaml
|
111
131
|
File.open(configuration_file, 'w') do |f|
|
112
132
|
f.write(config_file_contents)
|
113
133
|
end
|
114
134
|
end
|
115
135
|
|
116
136
|
def to_s
|
117
|
-
|
137
|
+
yaml.to_yaml.to_s
|
118
138
|
end
|
119
139
|
|
120
140
|
# class methods
|
@@ -44,6 +44,10 @@ module Lolcommits
|
|
44
44
|
warn "failed to load constant from plugin gem '#{plugin_klass_name}: #{e}'"
|
45
45
|
end
|
46
46
|
|
47
|
+
def plugin_instance(runner)
|
48
|
+
plugin_klass.new(runner: runner, config: runner.config.yaml[name])
|
49
|
+
end
|
50
|
+
|
47
51
|
def gem_name
|
48
52
|
gem_spec.name
|
49
53
|
end
|
@@ -55,7 +59,12 @@ module Lolcommits
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def plugin_klass_name
|
58
|
-
|
62
|
+
# convert gem paths to plugin classes e.g.
|
63
|
+
# lolcommits/loltext --> Lolcommits::Plugin::Loltext
|
64
|
+
# lolcommits/term_output --> Lolcommits::Plugin::TermOutput
|
65
|
+
gem_path.split('/').insert(1, 'plugin').collect do |c|
|
66
|
+
c.split('_').collect(&:capitalize).join
|
67
|
+
end.join('::')
|
59
68
|
end
|
60
69
|
end
|
61
70
|
end
|
@@ -1,30 +1,16 @@
|
|
1
|
+
require 'lolcommits/plugin/configuration_helper'
|
2
|
+
|
1
3
|
module Lolcommits
|
2
4
|
module Plugin
|
3
5
|
class Base
|
4
|
-
|
6
|
+
include Lolcommits::Plugin::ConfigurationHelper
|
5
7
|
|
6
|
-
|
7
|
-
self.runner = runner
|
8
|
-
self.config = config || runner.config
|
9
|
-
self.options = ['enabled']
|
10
|
-
end
|
11
|
-
|
12
|
-
def execute_pre_capture
|
13
|
-
return unless configured_and_enabled?
|
14
|
-
debug 'I am enabled, about to run pre capture'
|
15
|
-
run_pre_capture
|
16
|
-
end
|
8
|
+
attr_accessor :runner, :configuration, :options
|
17
9
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def execute_capture_ready
|
25
|
-
return unless configured_and_enabled?
|
26
|
-
debug 'I am enabled, about to run capture ready'
|
27
|
-
run_capture_ready
|
10
|
+
def initialize(runner: nil, config: {})
|
11
|
+
self.runner = runner
|
12
|
+
self.configuration = config || {}
|
13
|
+
self.options = [:enabled]
|
28
14
|
end
|
29
15
|
|
30
16
|
def run_pre_capture; end
|
@@ -33,57 +19,60 @@ module Lolcommits
|
|
33
19
|
|
34
20
|
def run_capture_ready; end
|
35
21
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
#
|
22
|
+
##
|
23
|
+
# Prompts the user to configure all plugin options.
|
24
|
+
#
|
25
|
+
# Available options can be defined in an Array (@options instance var)
|
26
|
+
# and/or a Hash (by overriding the `default_options` method).
|
27
|
+
#
|
28
|
+
# By default (on initialize), `@options` is set with `[:enabled]`. This is
|
29
|
+
# mandatory since `enabled?` checks this option is true before running any
|
30
|
+
# capture hooks.
|
31
|
+
#
|
32
|
+
# Using a Hash to define default options allows you to:
|
33
|
+
#
|
34
|
+
# - including default values
|
35
|
+
# - define nested options, user is prompted for each nested option key
|
36
|
+
#
|
37
|
+
# `configure_option_hash` will iterate over all options prompting the user
|
38
|
+
# for input and building the configuration Hash.
|
39
|
+
#
|
40
|
+
# Lolcommits will save this Hash to a YAML file. During the capture
|
41
|
+
# process the configuration is loaded, parsed and available in the plugin
|
42
|
+
# class as `@configuration`. Or if you want to fall back to default
|
43
|
+
# values, you should use `config_option` to fetch option values.
|
44
|
+
#
|
45
|
+
# Alternatively you can override this method entirely to customise the
|
46
|
+
# process. A helpful `parse_user_input` method is available to help parse
|
47
|
+
# strings from STDIN (into boolean, integer or nil values).
|
48
|
+
#
|
49
|
+
# @return [Hash] the configured plugin options
|
43
50
|
def configure_options!
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
val = parse_user_input(gets.strip)
|
48
|
-
# check enabled option isn't a String
|
49
|
-
if (option == 'enabled') && ![true, false].include?(val)
|
50
|
-
puts "Aborting - please respond with 'true' or 'false'"
|
51
|
-
exit 1
|
52
|
-
else
|
53
|
-
acc.merge(option => val)
|
54
|
-
end
|
55
|
-
end
|
51
|
+
configure_option_hash(
|
52
|
+
Hash[options.map { |key, _value| [key, nil] }].merge(default_options)
|
53
|
+
)
|
56
54
|
end
|
57
55
|
|
58
|
-
def
|
59
|
-
|
60
|
-
if 'true'.casecmp(str).zero?
|
61
|
-
true
|
62
|
-
elsif 'false'.casecmp(str).zero?
|
63
|
-
false
|
64
|
-
elsif str =~ /^[0-9]+$/
|
65
|
-
str.to_i
|
66
|
-
elsif str.strip.empty?
|
67
|
-
nil
|
68
|
-
else
|
69
|
-
str
|
70
|
-
end
|
56
|
+
def default_options
|
57
|
+
{}
|
71
58
|
end
|
72
59
|
|
73
|
-
def
|
74
|
-
|
60
|
+
def config_option(*keys)
|
61
|
+
configuration.dig(*keys) || default_options.dig(*keys)
|
75
62
|
end
|
76
63
|
|
77
64
|
def enabled?
|
78
|
-
|
65
|
+
# legacy configs (< 0.9.9) used a string key
|
66
|
+
configuration[:enabled] || configuration['enabled']
|
79
67
|
end
|
80
68
|
|
81
69
|
# check config is valid
|
82
70
|
def valid_configuration?
|
83
|
-
|
71
|
+
!configuration.empty?
|
84
72
|
end
|
85
73
|
|
86
74
|
# empty plugin configuration
|
75
|
+
# TODO: remove this method in after 0.9.9 release
|
87
76
|
def configured?
|
88
77
|
!configuration.empty?
|
89
78
|
end
|
@@ -92,12 +81,12 @@ module Lolcommits
|
|
92
81
|
# dont puts or print if the runner wants to be silent (stealth mode)
|
93
82
|
def puts(*args)
|
94
83
|
return if runner && runner.capture_stealth
|
95
|
-
super(args)
|
84
|
+
super(*args)
|
96
85
|
end
|
97
86
|
|
98
|
-
def print(args)
|
87
|
+
def print(*args)
|
99
88
|
return if runner && runner.capture_stealth
|
100
|
-
super(args)
|
89
|
+
super(*args)
|
101
90
|
end
|
102
91
|
|
103
92
|
# helper to log errors with a message via debug
|
@@ -111,11 +100,6 @@ module Lolcommits
|
|
111
100
|
super("#{self.class}: " + msg)
|
112
101
|
end
|
113
102
|
|
114
|
-
# identifying plugin name (for config, listing)
|
115
|
-
def self.name
|
116
|
-
'plugin'
|
117
|
-
end
|
118
|
-
|
119
103
|
# Returns position(s) of when a plugin should run during the capture
|
120
104
|
# process.
|
121
105
|
#
|
@@ -130,6 +114,29 @@ module Lolcommits
|
|
130
114
|
def self.runner_order
|
131
115
|
[]
|
132
116
|
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def configure_option_hash(option_hash, spacing_count = 0)
|
121
|
+
option_hash.keys.reduce({}) do |acc, option|
|
122
|
+
option_value = option_hash[option]
|
123
|
+
prefix = ' ' * spacing_count
|
124
|
+
if option_value.is_a?(Hash)
|
125
|
+
puts "#{prefix}#{option}:\n"
|
126
|
+
acc.merge(option => configure_option_hash(option_value, (spacing_count + 1)))
|
127
|
+
else
|
128
|
+
print "#{prefix}#{option.to_s.tr('_', ' ')}#{" (#{option_value})" unless option_value.nil?}: "
|
129
|
+
user_value = parse_user_input(gets.chomp.strip)
|
130
|
+
|
131
|
+
# if not enabled, disable and return without setting more options
|
132
|
+
# useful with nested hash configs, place enabled as first sub-option
|
133
|
+
# if answer is !true, no further sub-options will be prompted for
|
134
|
+
return { option => false } if option == :enabled && user_value != true
|
135
|
+
|
136
|
+
acc.merge(option => user_value)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
133
140
|
end
|
134
141
|
end
|
135
142
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
module Plugin
|
3
|
+
module ConfigurationHelper
|
4
|
+
# handle for bools, strings, ints and blanks from user input
|
5
|
+
def parse_user_input(str)
|
6
|
+
if 'true'.casecmp(str).zero?
|
7
|
+
true
|
8
|
+
elsif 'false'.casecmp(str).zero?
|
9
|
+
false
|
10
|
+
elsif str =~ /^[0-9]+$/
|
11
|
+
str.to_i
|
12
|
+
elsif str.strip.empty?
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# user input with autocomplete (via tab) through array of named values
|
20
|
+
#
|
21
|
+
# e.g.
|
22
|
+
# prompt_autocomplete_hash("Organization: ", orgs)
|
23
|
+
#
|
24
|
+
# where orgs are an array of hashes like so (with string keys):
|
25
|
+
# [
|
26
|
+
# { 'name' => 'some human readable name', 'value' => 1234 },
|
27
|
+
# ]
|
28
|
+
# User will be asked for Organization, can tab to autocomplete, and chosen
|
29
|
+
# value is returned.
|
30
|
+
def prompt_autocomplete_hash(prompt, items, name: 'name', value: 'value', suggest_words: 5)
|
31
|
+
words = items.map { |item| item[name] }.sort
|
32
|
+
puts "e.g. #{words.take(suggest_words).join(', ')}" if suggest_words > 0
|
33
|
+
completed_input = gets_autocomplete(prompt, words)
|
34
|
+
items.find { |item| item[name] == completed_input }[value]
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def gets_autocomplete(prompt, words)
|
40
|
+
completion_handler = proc { |s| words.grep(/^#{Regexp.escape(s)}/) }
|
41
|
+
Readline.completion_append_character = ''
|
42
|
+
Readline.completion_proc = completion_handler
|
43
|
+
|
44
|
+
while (line = Readline.readline(prompt, true).strip)
|
45
|
+
return line if words.include?(line)
|
46
|
+
puts "'#{line}' not found"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -8,6 +8,8 @@ module Lolcommits
|
|
8
8
|
pm
|
9
9
|
end
|
10
10
|
|
11
|
+
attr_reader :plugins
|
12
|
+
|
11
13
|
def initialize
|
12
14
|
@plugins = []
|
13
15
|
end
|
@@ -19,29 +21,22 @@ module Lolcommits
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def plugins_for(position)
|
22
|
-
|
24
|
+
@plugins.select do |plugin|
|
25
|
+
Array(plugin.plugin_klass.runner_order).include?(position)
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
|
-
# @return [Lolcommits::Plugin]
|
29
|
+
# @return [Lolcommits::Plugin] finds the first plugin matching name
|
26
30
|
def find_by_name(name)
|
27
|
-
|
31
|
+
@plugins.find { |plugin| plugin.name =~ /^#{name}/ } unless name.empty?
|
28
32
|
end
|
29
33
|
|
30
34
|
def plugin_names
|
31
|
-
|
32
|
-
# @plugins.map(&:name)
|
33
|
-
plugin_klasses.map(&:name).sort
|
35
|
+
@plugins.map(&:name).sort
|
34
36
|
end
|
35
37
|
|
36
38
|
private
|
37
39
|
|
38
|
-
# @return [Array] find all classes inheriting from Lolcommits::Plugin::Base
|
39
|
-
def plugin_klasses
|
40
|
-
# TODO: when all plugins are gems, change this to
|
41
|
-
# @plugins.map(&:plugin_klass)
|
42
|
-
ObjectSpace.each_object(Class).select { |klass| klass < Lolcommits::Plugin::Base }
|
43
|
-
end
|
44
|
-
|
45
40
|
# @return [Array] find all installed and supported plugins, populate
|
46
41
|
# @plugins array and return it
|
47
42
|
def find_plugins
|
data/lib/lolcommits/runner.rb
CHANGED
@@ -24,14 +24,27 @@ module Lolcommits
|
|
24
24
|
self.message = vcs_info.message if message.nil?
|
25
25
|
end
|
26
26
|
|
27
|
+
def execute_plugins_for(hook)
|
28
|
+
plugin_manager.plugins_for(hook).each do |gem_plugin|
|
29
|
+
plugin_name = gem_plugin.name
|
30
|
+
plugin = gem_plugin.plugin_instance(self)
|
31
|
+
next unless plugin.enabled?
|
32
|
+
|
33
|
+
if plugin.valid_configuration?
|
34
|
+
debug "Runner: #{plugin_name} is enabled with valid config, running #{hook}"
|
35
|
+
plugin.send("run_#{hook}")
|
36
|
+
else
|
37
|
+
puts "Warning: skipping plugin #{plugin_name} (invalid configuration, try: lolcommits --config -p #{plugin_name})"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
27
42
|
# wrap run to handle things that should happen before and after
|
28
43
|
# this used to be handled with ActiveSupport::Callbacks, but
|
29
44
|
# now we're just using a simple procedural list
|
30
45
|
def run
|
31
46
|
# do plugins that need to happen before capture
|
32
|
-
|
33
|
-
plugin.new(runner: self).execute_pre_capture
|
34
|
-
end
|
47
|
+
execute_plugins_for(:pre_capture)
|
35
48
|
|
36
49
|
# do main capture to snapshot_loc
|
37
50
|
run_capture
|
@@ -42,14 +55,10 @@ module Lolcommits
|
|
42
55
|
resize_snapshot!
|
43
56
|
|
44
57
|
# execute post_capture plugins, use to alter the capture
|
45
|
-
|
46
|
-
plugin.new(runner: self).execute_post_capture
|
47
|
-
end
|
58
|
+
execute_plugins_for(:post_capture)
|
48
59
|
|
49
60
|
# execute capture_ready plugins, capture is ready for export/sharing
|
50
|
-
|
51
|
-
plugin.new(runner: self).execute_capture_ready
|
52
|
-
end
|
61
|
+
execute_plugins_for(:capture_ready)
|
53
62
|
|
54
63
|
# clean away any tmp files
|
55
64
|
cleanup!
|
data/lib/lolcommits/version.rb
CHANGED
data/lolcommits.gemspec
CHANGED
@@ -64,13 +64,12 @@ POSTINSTALL
|
|
64
64
|
s.add_runtime_dependency('git', '~> 1.3.0')
|
65
65
|
|
66
66
|
# included plugins
|
67
|
-
s.add_runtime_dependency('lolcommits-loltext', '~> 0.0.
|
67
|
+
s.add_runtime_dependency('lolcommits-loltext', '~> 0.0.5')
|
68
68
|
|
69
69
|
# development & test gems
|
70
70
|
s.add_development_dependency('rdoc')
|
71
71
|
s.add_development_dependency('pry')
|
72
72
|
s.add_development_dependency('rubocop')
|
73
|
-
s.add_development_dependency('travis')
|
74
73
|
s.add_development_dependency('minitest')
|
75
74
|
s.add_development_dependency('coveralls')
|
76
75
|
s.add_development_dependency('ffaker')
|
data/test/lolcommits_test.rb
CHANGED
@@ -23,10 +23,10 @@ class LolTest < MiniTest::Test
|
|
23
23
|
commandcam_perms = File.lstat(File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', 'CommandCam', 'CommandCam.exe')).mode & 0o777
|
24
24
|
|
25
25
|
assert imagesnap_perms == 0o755 || imagesnap_perms == 0o775,
|
26
|
-
"expected perms of 755/775 but instead got #{format '
|
26
|
+
"expected perms of 755/775 but instead got #{format '%<perms>o', perms: imagesnap_perms}"
|
27
27
|
assert videosnap_perms == 0o755 || videosnap_perms == 0o775,
|
28
|
-
"expected perms of 755/775 but instead got #{format '
|
28
|
+
"expected perms of 755/775 but instead got #{format '%<perms>o', perms: videosnap_perms}"
|
29
29
|
assert commandcam_perms == 0o755 || commandcam_perms == 0o775,
|
30
|
-
"expected perms of 755/775 but instead got #{format '
|
30
|
+
"expected perms of 755/775 but instead got #{format '%<perms>o', perms: commandcam_perms}"
|
31
31
|
end
|
32
32
|
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.
|
4
|
+
version: 0.10.0.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:
|
12
|
+
date: 2018-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aruba
|
@@ -171,14 +171,14 @@ dependencies:
|
|
171
171
|
requirements:
|
172
172
|
- - "~>"
|
173
173
|
- !ruby/object:Gem::Version
|
174
|
-
version: 0.0.
|
174
|
+
version: 0.0.5
|
175
175
|
type: :runtime
|
176
176
|
prerelease: false
|
177
177
|
version_requirements: !ruby/object:Gem::Requirement
|
178
178
|
requirements:
|
179
179
|
- - "~>"
|
180
180
|
- !ruby/object:Gem::Version
|
181
|
-
version: 0.0.
|
181
|
+
version: 0.0.5
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
183
|
name: rdoc
|
184
184
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,20 +221,6 @@ dependencies:
|
|
221
221
|
- - ">="
|
222
222
|
- !ruby/object:Gem::Version
|
223
223
|
version: '0'
|
224
|
-
- !ruby/object:Gem::Dependency
|
225
|
-
name: travis
|
226
|
-
requirement: !ruby/object:Gem::Requirement
|
227
|
-
requirements:
|
228
|
-
- - ">="
|
229
|
-
- !ruby/object:Gem::Version
|
230
|
-
version: '0'
|
231
|
-
type: :development
|
232
|
-
prerelease: false
|
233
|
-
version_requirements: !ruby/object:Gem::Requirement
|
234
|
-
requirements:
|
235
|
-
- - ">="
|
236
|
-
- !ruby/object:Gem::Version
|
237
|
-
version: '0'
|
238
224
|
- !ruby/object:Gem::Dependency
|
239
225
|
name: minitest
|
240
226
|
requirement: !ruby/object:Gem::Requirement
|
@@ -309,10 +295,10 @@ files:
|
|
309
295
|
- config/cucumber.yml
|
310
296
|
- features/bugs.feature
|
311
297
|
- features/lolcommits.feature
|
312
|
-
- features/plugins.feature
|
313
298
|
- features/step_definitions/lolcommits_steps.rb
|
314
299
|
- features/support/env.rb
|
315
300
|
- features/support/path_helpers.rb
|
301
|
+
- lib/core_ext/hash/hash_dig.rb
|
316
302
|
- lib/core_ext/mercurial-ruby/command.rb
|
317
303
|
- lib/core_ext/mercurial-ruby/shell.rb
|
318
304
|
- lib/core_ext/mini_magick/utilities.rb
|
@@ -340,6 +326,7 @@ files:
|
|
340
326
|
- lib/lolcommits/installation.rb
|
341
327
|
- lib/lolcommits/platform.rb
|
342
328
|
- lib/lolcommits/plugin/base.rb
|
329
|
+
- lib/lolcommits/plugin/configuration_helper.rb
|
343
330
|
- lib/lolcommits/plugin/lol_yammer.rb
|
344
331
|
- lib/lolcommits/plugin_manager.rb
|
345
332
|
- lib/lolcommits/runner.rb
|
@@ -388,9 +375,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
388
375
|
version: '2.0'
|
389
376
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
390
377
|
requirements:
|
391
|
-
- - "
|
378
|
+
- - ">"
|
392
379
|
- !ruby/object:Gem::Version
|
393
|
-
version:
|
380
|
+
version: 1.3.1
|
394
381
|
requirements:
|
395
382
|
- imagemagick
|
396
383
|
- a webcam
|
@@ -399,4 +386,11 @@ rubygems_version: 2.7.3
|
|
399
386
|
signing_key:
|
400
387
|
specification_version: 4
|
401
388
|
summary: Capture webcam image on git commit for lulz.
|
402
|
-
test_files:
|
389
|
+
test_files:
|
390
|
+
- features/bugs.feature
|
391
|
+
- features/lolcommits.feature
|
392
|
+
- features/step_definitions/lolcommits_steps.rb
|
393
|
+
- features/support/env.rb
|
394
|
+
- features/support/path_helpers.rb
|
395
|
+
- test/images/test_image.jpg
|
396
|
+
- test/lolcommits_test.rb
|
data/features/plugins.feature
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Feature: Plugins Work
|
2
|
-
|
3
|
-
Background:
|
4
|
-
Given a mocked home directory
|
5
|
-
|
6
|
-
@slow_process @unstable
|
7
|
-
Scenario: Lolcommits.com integration works
|
8
|
-
Given I am in a git repo named "dot_com" with lolcommits enabled
|
9
|
-
When I run `lolcommits --config` interactively
|
10
|
-
And I wait for output to contain "Name of plugin to configure:"
|
11
|
-
Then I type "dot_com"
|
12
|
-
And I wait for output to contain "enabled:"
|
13
|
-
Then I type "true"
|
14
|
-
And I wait for output to contain "api_key:"
|
15
|
-
Then I type "b2a70ac0b64e012fa61522000a8c42dc"
|
16
|
-
And I wait for output to contain "api_secret:"
|
17
|
-
Then I type "b2a70ac0b64e012fa61522000a8c42dc"
|
18
|
-
And I wait for output to contain "repo_id:"
|
19
|
-
Then I type "b2a70ac0b64e012fa61522000a8c42dc"
|
20
|
-
Then the output should contain "Successfully configured plugin: dot_com"
|