mvn2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3d25d900f40c6578c29991f7d1c234f7894b8a1c
4
+ data.tar.gz: 3e3881f9756edc657c746efadb2f89e44706bd89
5
+ SHA512:
6
+ metadata.gz: f9f4feef2d939bc73012ab565262428faa9d113c1a86705bca6932206aa7a30cebbb404ac2d9b900402fa7210124c6b6917f4970f0387c30e927155d10d4ed7e
7
+ data.tar.gz: f1c75f175b6834fcb2660465335558b5d39d37120f80e34d46c695475b09b157f85e38101da59a188cd2276e11111e8018eac81d0715f4707b1a0d0f4c3ac05f
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ /.idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mvn2.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eric Henderson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # mvn2
2
+
3
+ A Ruby script that runs a maven build, including (or not including) tests, and only outputs the lines that come after a compile failure, build success, test result, or reactor summary start line
4
+
5
+ ## Installation
6
+
7
+ Install it yourself as:
8
+
9
+ $ gem install mvn2
10
+
11
+ ## Usage
12
+
13
+ ###optional parameters:
14
+ * `-t` or `--timer` to display a timer while the build is in progress (default is display nothing)
15
+ * `-s` or `--skip-tests` to skip tests (default is running tests)
16
+ * `-n` or `--no-sticky` to make the growl notification non-sticky (default is sticky)
17
+ * `-a` or `--display-all` to display all output (default is to only display the output after a compile failure, build success, test result, or reactor summary start line)
18
+ * `-k` or `--track-average` to update the average (stored in `avg.txt`) and also display a progress bar while the build is in progress (default is not to do track average or display progress bar)
19
+ * `-u` or `--track-full-average` to update the average list (stored in `avg-skip.txt` or `avg-test.txt`) and also display a progress bar while the build is in progress (default is to not do track average or display progress bar) (including this option will cause the progress bar to use the average calculated from the average list if available, but if `-k` or `--track-average` is specified, `avg.txt` will still be updated)
20
+ * `-c` or `--colored` to display some colors in the timer/progress message
21
+ * `--write-log` to write all of the output to a log file (default is to not write to a log file)
22
+ * `--log-file NAME` to set the log file name to `NAME` (default is `build.log`)
23
+ * `-d` or `--advanced-average` to use k-means (with minimum optimal k) to find a list of averages and use the closest one for the progress bar and displayed average (default is to use overall average)
24
+ * `--command-override CMD` to override the maven command (disables average tracking options and skip test option) (default is `clean install` (with optional `-D skipTests`) and not disabling any options)
25
+ * `-p` or `--package` to run `mvn clean package` (with optional `-D skipTests`) (default is `mvn clean install` (with optional `-D skipTests`) (supports average tracking)
26
+ * `-h` or `--hide-between` to hide the output between the end of test results (the line starting with "Tests run:") and the next trigger line
27
+ * `-w` or `--show-average` to show the average(s) before and after the build (average tracking must be enabled) (default is to not show averages)
28
+ * `-b` or `--block-update` to block the average feature from updating the file(s)
29
+ * `-v` or `--override-colors` to override the colors with the ones configured by the [colorconfig][colorconfig] script
30
+ * `-j` or `--show-projects` to show the `Building <project>` lines when outputting
31
+ * `--run-before CMD` to run `CMD` before calling the maven build
32
+ * `--run-after CMD` to run `CMD` after finishing the maven build
33
+ * `--run-success CMD` to run `CMD` after finishing a successful maven build
34
+ * `--run-failure CMD` to run `CMD` after finishing an unsuccessful maven build
35
+ * `-e` or `--exception` to add the `-e -X` options to the `mvn` call
36
+ * `-0` or `--live-print` to print filtered lines as they are outputted by maven
37
+ * `-1` or `--set-defaults` to set the defaults so you can just run `mvn2` without any parameters
38
+ * `--mobile-number NUM` to use the mobile number `NUM` (with country code and nothing other than digits) (country code for US is 1 so an example phone number would be `--mobile-number "13175649047"`) as the recipient of a text message (from **13179120742**) indicating the success or failure of a build and the name of the immediate folder of the build (requires gem `nexmo`)
39
+ * `-2` or `--advanced-text` to upload the folder name, build time so far, and estimated percent complete (based on stored averages) to a server so that you can text **13179120742** (the number you get the build completion texts from) to get the status(es) of your ongoing build(s). If you send the exact name of the folder (case-**sensitive**, only 1 at a time), it will only reply with entries matching that build. If you text anything that does not exactly match a folder name, it will simply reply with all of the ongoing build statuses. It identifies your builds by your mobile number, so make sure you're texting from the number you used as the parameter to the `--mobile-number NUM` option.
40
+
41
+ ###displays:
42
+ a Growl notification indicating success or failure
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/mvn2 ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+ require 'net/http'
6
+ require 'rubygems'
7
+ require 'everyday-cli-utils'
8
+ include EverydayCliUtils
9
+ import :maputil, :format, :kmeans, :option
10
+ require 'mvn2/plugin'
11
+ begin
12
+ Gem.find_latest_files('/mvn2/plugin/*.plugin.rb').each { |plugin|
13
+ #noinspection RubyResolve
14
+ begin
15
+ require plugin
16
+ rescue LoadError => e
17
+ puts "Error in loading plugin '#{plugin}'"
18
+ puts e.inspect
19
+ end
20
+ }
21
+ rescue Exception => e
22
+ puts 'Error in loading plugins'
23
+ puts e.inspect
24
+ end
25
+
26
+ #abcd h jkl n p stuvw 012
27
+ # efg i m o qr xyz 3456789
28
+
29
+ class MyOptions
30
+ extend OptionUtil
31
+
32
+ default_settings toggle: true
33
+
34
+ defaults_option 'mvn2-defaults.yaml', %w(-1 --set-defaults), desc: 'set the defaults so you can just run mvn2 without any parameters (local to each folder)'
35
+
36
+ help_option ['--help'], desc: 'print out this help'
37
+ end
38
+
39
+ Mvn2::Plugins.get(:option, MyOptions)
40
+ Mvn2::Plugins.get(:option_with_param, MyOptions)
41
+
42
+ MyOptions.parse!
43
+
44
+ options = MyOptions.options
45
+
46
+ Mvn2::Plugins.set_var(:options, options)
47
+
48
+ Signal.trap('SIGINT') {
49
+ puts "\nBuild Canceled\n\n"
50
+ exit 1
51
+ }
52
+
53
+ class String
54
+ def start_with_any?(*strs)
55
+ strs.empty? ? false : strs.any? { |str| start_with?(str) }
56
+ end
57
+ end
58
+
59
+ Mvn2::Plugins.get :color_override
60
+
61
+ class Mvn2Runner
62
+ HEADLESS = ' -Djava.awt.headless=true'
63
+ INFO_LINE = '[INFO] ------------------------------------------------------------------------'
64
+ BUILD_REGEX = /\[INFO\] Building (?!(jar|war|zip))/
65
+
66
+ def initialize(options)
67
+ @options = options
68
+ setup_cmd
69
+ Mvn2::Plugins.set_var :cmd, @cmd
70
+ Mvn2::Plugins.set_var :cmd_clean, @cmd_clean
71
+ end
72
+
73
+ def setup_cmd
74
+ flags = Mvn2::Plugins.get :command_flag
75
+ goals = Mvn2::Plugins.get :goal_override
76
+ @cmd = "mvn #{goals}#{flags}#{HEADLESS} 2>&1"
77
+ @cmd_clean = @cmd[0...(-5-HEADLESS.length)]
78
+ end
79
+
80
+ def run_and_filter_output
81
+ Mvn2::Plugins.get :before_run
82
+ @result = Mvn2::Plugins.get :runner
83
+ Mvn2::Plugins.get :after_run
84
+ end
85
+
86
+ def run
87
+ Mvn2::Plugins.get :before_start
88
+ run_and_filter_output
89
+ Mvn2::Plugins.get :after_end
90
+
91
+ operation_name = Mvn2::Plugins.get :operation_name
92
+ Mvn2::Plugins.set_var :message_text, "#{operation_name} #{(@result ? 'Successful' : 'Failed')}"
93
+
94
+ Mvn2::Plugins.get :notification
95
+ end
96
+ end
97
+
98
+ Mvn2Runner.new(options).run
@@ -0,0 +1,204 @@
1
+ require 'mvn2/plugin'
2
+ class AvgPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register_variable :average
7
+ register_variable :averages2
8
+ register_variable :counts
9
+
10
+ register_type(:full_avg_name) { |list|
11
+ options = Mvn2::Plugins.get_var :options
12
+ pieces = []
13
+ list.sort_by { |v| v[:options][:order] }.each { |name| pieces << name[:block].call(options) }
14
+ pieces.join
15
+ }
16
+
17
+ register_type(:block_average) { |list|
18
+ options = Mvn2::Plugins.get_var :options
19
+ list.any? { |item|
20
+ if item[:block].nil?
21
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
22
+ else
23
+ item[:block].call(options)
24
+ end
25
+ }
26
+ }
27
+
28
+ register_type(:block_update) { |list|
29
+ options = Mvn2::Plugins.get_var :options
30
+ result = Mvn2::Plugins.get_var :result
31
+ average = Mvn2::Plugins.get_var :average
32
+ diff = Mvn2::Plugins.get_var :diff
33
+ list.any? { |item|
34
+ if item[:block].nil?
35
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
36
+ else
37
+ item[:block].call(options, result, average, diff)
38
+ end
39
+ }
40
+ }
41
+
42
+ register_type(:block_full_average) { |list|
43
+ if Mvn2::Plugins.get(:block_average)
44
+ true
45
+ else
46
+ options = Mvn2::Plugins.get_var :options
47
+ list.any? { |item|
48
+ if item[:block].nil?
49
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
50
+ else
51
+ item[:block].call(options)
52
+ end
53
+ }
54
+ end
55
+ }
56
+
57
+ register :option, sym: :track_average, names: %w(-k --track-average), desc: 'update the average and also display a progress bar while the build is in progress'
58
+
59
+ register :option, sym: :track_full_average, names: %w(-u --track-full-average), desc: 'update the average list and also display a progress bar while the build is in progress'
60
+
61
+ register :option, sym: :advanced_average, names: %w(-d --advanced-average), desc: 'use k-means (with minimum optimal k) to find a list of averages and use the closest one for the progress bar and displayed average'
62
+
63
+ register :option, sym: :show_average, names: %w(-w --show-average), desc: 'show the average(s) before and after the build (average tracking must be enabled)'
64
+
65
+ register :option, sym: :block_update, names: %w(-b --block-update), desc: 'block the average feature from updating the file(s)'
66
+
67
+ register :block_update, option: :block_update
68
+
69
+ register(:block_update) { |options, result, average, diff| !(result || (!options[:skip_tests] && diff >= average / 2.0)) }
70
+
71
+ register :block_full_average, option: :track_full_average, value: false
72
+
73
+ register :block_average, option: :track_average, value: false
74
+
75
+ register(:before_run, order: 1) { |options|
76
+ read_avg
77
+ read_full_avg
78
+ read_advanced_avg
79
+ show_averages if options[:show_average]
80
+ }
81
+
82
+ register(:after_run, order: 2) { |_, _|
83
+ update_avg
84
+ update_full_avg
85
+ }
86
+
87
+ register(:after_run, order: 4) { |options, _|
88
+ if options[:show_average]
89
+ read_avg
90
+ read_full_avg
91
+ read_advanced_avg
92
+ show_averages
93
+ end
94
+ }
95
+
96
+ def self.full_avg_file
97
+ pieces = Mvn2::Plugins.get :full_avg_name
98
+ "avg#{pieces}.txt"
99
+ end
100
+
101
+ def self.float_filter(line)
102
+ begin
103
+ f = line.chomp
104
+ f.length == 0 || (f =~ /^\d+(\.\d+)?$/).nil? ? false : f.to_f
105
+ rescue
106
+ false
107
+ end
108
+ end
109
+
110
+ def self.read_full_avg
111
+ average = Mvn2::Plugins.get_var :average
112
+ file_name = full_avg_file
113
+ if !Mvn2::Plugins.get(:block_full_average) && File.exist?(file_name)
114
+ lines = IO.readlines(file_name)
115
+ data = lines.filtermap { |line| float_filter(line) }
116
+ average = data.average
117
+ end
118
+ Mvn2::Plugins.set_var :average, average
119
+ end
120
+
121
+ def self.read_advanced_avg
122
+ options = Mvn2::Plugins.get_var :options
123
+ average = Mvn2::Plugins.get_var :average
124
+ averages = [average]
125
+ file_name = full_avg_file
126
+ if !Mvn2::Plugins.get(:block_full_average) && options[:advanced_average] && File.exist?(file_name)
127
+ lines = IO.readlines(file_name)
128
+ data = lines.filtermap { |line| float_filter(line) }
129
+ averages = data.nmeans
130
+ end
131
+ Mvn2::Plugins.set_var :averages, averages
132
+ end
133
+
134
+ def self.update_full_avg
135
+ diff = Mvn2::Plugins.get_var :diff
136
+ if !Mvn2::Plugins.get(:block_full_average) && !Mvn2::Plugins.get(:block_update)
137
+ file = File.new(full_avg_file, 'a+')
138
+ file.puts(diff)
139
+ file.close
140
+ end
141
+ end
142
+
143
+ def self.get_data(averages, counts, lines, ind)
144
+ if lines.count > ind
145
+ parts = lines[ind].chomp.split(';')
146
+ averages[ind] = parts[0].to_f
147
+ counts[ind] = parts[1].to_i
148
+ averages[ind] = 0 if counts[ind] == 0
149
+ end
150
+ end
151
+
152
+ def self.read_avg
153
+ options = Mvn2::Plugins.get_var :options
154
+ average = 0
155
+ averages = [0, 0, 0, 0]
156
+ counts = [0, 0, 0, 0]
157
+ if !Mvn2::Plugins.get(:block_average) && File.exist?('avg.txt')
158
+ lines = IO.readlines('avg.txt')
159
+ get_data(averages, counts, lines, 0)
160
+ get_data(averages, counts, lines, 1)
161
+ get_data(averages, counts, lines, 2)
162
+ get_data(averages, counts, lines, 3)
163
+ pkg = options[:package] ? 2 : 0
164
+ average = averages[(options[:skip_tests] ? 0 : 1) + pkg]
165
+ end
166
+ Mvn2::Plugins.set_var :average, average
167
+ Mvn2::Plugins.set_var :averages2, averages
168
+ Mvn2::Plugins.set_var :counts, counts
169
+ end
170
+
171
+ def self.calc_new_avg(ind)
172
+ averages2 = Mvn2::Plugins.get_var :averages2
173
+ counts = Mvn2::Plugins.get_var :counts
174
+ diff = Mvn2::Plugins.get_var :diff
175
+ sum = averages2[ind] * counts[ind] + diff
176
+ counts[ind] += 1
177
+ averages2[ind] = sum / counts[ind]
178
+ end
179
+
180
+ def self.update_avg
181
+ options = Mvn2::Plugins.get_var :options
182
+ averages2 = Mvn2::Plugins.get_var :averages2
183
+ counts = Mvn2::Plugins.get_var :counts
184
+ if !Mvn2::Plugins.get(:block_average) && !Mvn2::Plugins.get(:block_update)
185
+ options[:skip_tests] ? calc_new_avg(0) : calc_new_avg(1)
186
+ IO.write('avg.txt', "#{averages2[0]};#{counts[0]}\n#{averages2[1]};#{counts[1]}\n#{averages2[2]};#{counts[2]}\n#{averages2[3]};#{counts[3]}")
187
+ end
188
+ end
189
+
190
+ def self.show_averages
191
+ averages = Mvn2::Plugins.get_var :averages
192
+ unless averages.empty? || (averages.length == 1 && averages[0] == 0)
193
+ strs = averages.map { |a|
194
+ m, s = get_time_parts(a)
195
+ "#{m}:#{s}"
196
+ }
197
+ puts "\r\e[2KAverage(s): #{strs.join(', ')}"
198
+ end
199
+ end
200
+
201
+ def self.get_time_parts(time)
202
+ return (time / 60.0).floor, '%06.3f' % (time % 60)
203
+ end
204
+ end
@@ -0,0 +1,39 @@
1
+ require 'mvn2/plugin'
2
+ class CommandPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register :option_with_param, sym: :command_override, names: ['--command-override'], desc: 'override the maven command (disables average tracking options and skip test option)'
7
+
8
+ register :option, sym: :package, names: %w(-p --package), desc: 'run "mvn clean package" (with optional "-D skipTests")'
9
+
10
+ register :option_with_param, sym: :run_before, names: ['--run-before'], desc: 'run a command before calling the maven build'
11
+ register :option_with_param, sym: :run_after, names: ['--run-after'], desc: 'run a command after finishing the maven build'
12
+ register :option_with_param, sym: :run_success, names: ['--run-success'], desc: 'run a command after finishing a successful maven build'
13
+ register :option_with_param, sym: :run_failure, names: ['--run-failure'], desc: 'run a command after finishing an unsuccessful maven build'
14
+
15
+ register :goal_override, order: 10, option: :package, goal: 'package'
16
+
17
+ register :goal_override, override_all: true, priority: 100, option: :command_override
18
+
19
+ register(:full_avg_name, order: 20) { |options| options[:package] ? '-package' : '' }
20
+
21
+ register(:operation_name, priority: 100) { |options| options[:command_override].nil? ? nil : 'Operation' }
22
+
23
+ register(:block_average) { |options| !options[:command_override].nil? }
24
+
25
+ register(:before_start, order: 10) { |options| run_cmd(options[:run_before]) }
26
+
27
+ register(:after_end, order: 10) { |options, result|
28
+ run_cmd(options[:run_after])
29
+ result ? run_cmd(options[:run_success]) : run_cmd(options[:run_failure])
30
+ }
31
+
32
+ def self.run_cmd(cmd)
33
+ unless cmd.nil?
34
+ puts "$ #{cmd}"
35
+ system(cmd)
36
+ print "\n"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ require 'mvn2/plugin'
2
+ class DefaultRunnerPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register_variable :output
7
+
8
+ register(:runner_enable, key: :default) { |_| true }
9
+
10
+ register(:runner, key: :default, priority: 0) { |_, cmd|
11
+ output = `#{cmd}`
12
+ result = $?.success?
13
+ Mvn2::Plugins.set_var :output, output
14
+ result
15
+ }
16
+
17
+ register(:after_run, order: 1000) { |_, _|
18
+ runner = Mvn2::Plugins.get_var :runner
19
+ if runner == :default
20
+ output = Mvn2::Plugins.get_var :output
21
+ IO.write(Mvn2::Plugins.get(:log_file_name), output) if Mvn2::Plugins.get(:log_file_enable)
22
+ output.each_line { |l|
23
+ tmp = Mvn2::Plugins.get :line_filter, l
24
+ puts tmp unless tmp.nil?
25
+ }
26
+ found = Mvn2::Plugins.get_var :found
27
+ output.each_line { |line| puts line } unless found
28
+ end
29
+ }
30
+ end
@@ -0,0 +1,8 @@
1
+ require 'mvn2/plugin'
2
+ class ExceptionPlugin
3
+ extend Mvn2::Plugin
4
+
5
+ register :option, sym: :exception, names: %w(-e --exception), desc: 'add the "-e -X" options to the mvn call'
6
+
7
+ register :command_flag, flag: '-e -X', option: :exception
8
+ end
@@ -0,0 +1,85 @@
1
+ require 'mvn2/plugin'
2
+
3
+ class String
4
+ def start_with_any?(*strs)
5
+ strs.empty? ? false : strs.any? { |str| start_with?(str) }
6
+ end
7
+ end
8
+
9
+ class FilterPlugin
10
+ extend Mvn2::Plugin
11
+ extend Mvn2::PluginType
12
+
13
+ INFO_LINE = '[INFO] ------------------------------------------------------------------------'
14
+ BUILD_REGEX = /\[INFO\] Building (?!(jar|war|zip))/
15
+
16
+ register_variable :info_line_last, false
17
+ register_variable :found, false
18
+
19
+ register :option, sym: :hide_between, names: %w(-h --hide-between), desc: 'hide the output between the end of test results (the line starting with "Tests run:") and the next trigger line'
20
+
21
+ register :option, sym: :show_projects, names: %w(-j --show-projects), desc: 'show the "Building <project>" lines when outputting'
22
+
23
+ register(:line_filter, priority: 10) { |_, line|
24
+ info_line_last = Mvn2::Plugins.get_var :info_line_last
25
+ if line.start_with_any?('[INFO] BUILD SUCCESS', '[INFO] Reactor Summary:', '[INFO] BUILD FAILURE')
26
+ str = ''
27
+ str << INFO_LINE << "\n" unless info_line_last
28
+ str << line << "\n"
29
+ Mvn2::Plugins.set_var :found, true
30
+ Mvn2::Plugins.set_var :info_line_last, false
31
+ str
32
+ else
33
+ nil
34
+ end
35
+ }
36
+
37
+ register(:line_filter, priority: 20) { |_, line|
38
+ if line.start_with_any?('[ERROR] COMPILATION ERROR :', 'Results :')
39
+ str = line << "\n"
40
+ Mvn2::Plugins.set_var :found, true
41
+ Mvn2::Plugins.set_var :info_line_last, false
42
+ str
43
+ else
44
+ nil
45
+ end
46
+ }
47
+
48
+ register(:line_filter, priority: 30) { |_, line|
49
+ found = Mvn2::Plugins.get_var :found
50
+ if found
51
+ str = line << "\n"
52
+ Mvn2::Plugins.set_var :found, true
53
+ Mvn2::Plugins.set_var :info_line_last, line.start_with?(INFO_LINE)
54
+ str
55
+ else
56
+ nil
57
+ end
58
+ }
59
+
60
+ register(:line_filter, priority: 40) { |options, line|
61
+ found = Mvn2::Plugins.get_var :found
62
+ if options[:hide_between] && found && line.start_with?('Tests run:')
63
+ str = line << "\n\n"
64
+ Mvn2::Plugins.set_var :found, false
65
+ Mvn2::Plugins.set_var :info_line_last, false
66
+ str
67
+ else
68
+ nil
69
+ end
70
+ }
71
+
72
+ register(:line_filter, priority: 50) { |options, line|
73
+ info_line_last = Mvn2::Plugins.get_var :info_line_last
74
+ if options[:show_projects] && line =~ BUILD_REGEX
75
+ str = ''
76
+ str << INFO_LINE << "\n" unless info_line_last
77
+ str << line << "\n"
78
+ str << INFO_LINE << "\n"
79
+ Mvn2::Plugins.set_var :info_line_last, true
80
+ str
81
+ else
82
+ nil
83
+ end
84
+ }
85
+ end
@@ -0,0 +1,13 @@
1
+ require 'mvn2/plugin'
2
+ class GrowlPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register :option, sym: :no_sticky, names: %w(-n --no-sticky), desc: 'make the growl notification non-sticky'
7
+
8
+ register(:notification, order: 100) { |options, _, cmd_clean, message_text|
9
+ begin
10
+ `growlnotify -n Terminal -a Terminal#{(options[:no_sticky] ? '' : ' -s')} -m "#{message_text}" -t "#{cmd_clean}" 2>&1`
11
+ end until $?.success?
12
+ }
13
+ end
@@ -0,0 +1,29 @@
1
+ require 'mvn2/plugin'
2
+ class LivePrintPlugin
3
+ extend Mvn2::Plugin
4
+
5
+ register :option, sym: :display_all, names: %w(-a --display-all), desc: 'display all output'
6
+
7
+ register :option, sym: :live_print, names: %w(-0 --live-print), desc: 'print filtered lines as they are outputted by maven'
8
+
9
+ register(:line_filter, priority: 10 ** 6) { |options, line| options[:display_all] ? line : nil }
10
+
11
+ register :runner_enable, key: :live_print, option: :live_print
12
+ register :runner_enable, key: :live_print, option: :display_all
13
+
14
+ register(:runner, key: :live_print, priority: 1000) { |_, cmd|
15
+ result = false
16
+ begin
17
+ log_file = Mvn2::Plugins.get(:log_file_enable) ? File.open(Mvn2::Plugins.get(:log_file_name), 'w+') : nil
18
+ IO.popen(cmd).each do |l|
19
+ log_file << l unless log_file.nil?
20
+ output = Mvn2::Plugins.get :line_filter, l
21
+ puts "\r\e[2K#{output}" unless output.nil?
22
+ result = true if l.chomp.start_with?('[INFO] BUILD SUCCESS')
23
+ end
24
+ ensure
25
+ log_file.close unless log_file.nil?
26
+ end
27
+ result
28
+ }
29
+ end
@@ -0,0 +1,12 @@
1
+ require 'mvn2/plugin'
2
+ class LoggingPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register :option, sym: :write_log, names: %w(-l --write-log), desc: 'write all of the output to a log file'
7
+ register :option_with_param, sym: :log_file, names: ['--log-file'], desc: 'set the log file name', default: 'build.log'
8
+
9
+ register :log_file_name, priority: 1000, option: :log_file
10
+
11
+ register :log_file_enable, option: :write_log
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'mvn2/plugin'
2
+ class SkipTestsPlugin
3
+ extend Mvn2::Plugin
4
+
5
+ register :option, sym: :skip_tests, names: %w(-s --skip-tests), desc: 'skip tests'
6
+
7
+ register :command_flag, flag: '-D skipTests', option: :skip_tests
8
+
9
+ register(:full_avg_name, order: 10) { |options| options[:skip_tests] ? '-skip' : '-test' }
10
+
11
+ register(:operation_name, priority: 10) { |options| options[:skip_tests] ? 'Build' : 'Tests' }
12
+ end
@@ -0,0 +1,66 @@
1
+ require 'mvn2/plugin'
2
+ class TimerPlugin
3
+ extend Mvn2::Plugin
4
+ extend Mvn2::PluginType
5
+
6
+ register_variable :time1
7
+ register_variable :diff
8
+ register_variable :thread
9
+
10
+ register :option, sym: :timer, names: %w(-t --timer), desc: 'display a timer while the build is in progress'
11
+
12
+ register :option, sym: :colored, names: %w(-c --colored), desc: 'display some colors in the timer/progress message'
13
+
14
+ register(:before_run, order: 2) { |options|
15
+ Mvn2::Plugins.set_var :time1, Time.now
16
+ Mvn2::Plugins.set_var :thread, options[:timer] ? Thread.new {
17
+ start_time = Mvn2::Plugins.get_var :time1
18
+ while true
19
+ print "\r#{get_timer_message(start_time, Time.now)}"
20
+ sleep(0.05)
21
+ end
22
+ } : nil
23
+ }
24
+
25
+ register(:after_run, order: 1) { |_, _|
26
+ time2 = Time.now
27
+ time1 = Mvn2::Plugins.get_var :time1
28
+ Mvn2::Plugins.set_var :diff, time2 - time1
29
+ }
30
+
31
+ register(:after_run, order: 3) { |_, _|
32
+ thread = Mvn2::Plugins.get_var :thread
33
+ unless thread.nil?
34
+ thread.kill
35
+ print "\n"
36
+ end
37
+ }
38
+
39
+ def self.colorize_if_should(text)
40
+ options = Mvn2::Plugins.get_var :options
41
+ options[:colored] ? text.format_all : text.remove_format
42
+ end
43
+
44
+ def self.get_avg_message(amin, asec, avg, diff, m, s)
45
+ progress = ((diff.to_f / avg.to_f) * 100.0)
46
+ bars = [progress.floor, 100].min
47
+ "[#{'=' * bars}>#{' ' * (100 - bars)}] {#{m}:#{s}}(:time) ({~#{'%.3f' % progress}%}(:percent)) (average: {#{amin}:#{asec}}(:average))"
48
+ end
49
+
50
+ def self.get_closest(time)
51
+ averages = Mvn2::Plugins.get_var :averages
52
+ averages.min { |a, b| (a - time).abs <=> (b - time).abs }
53
+ end
54
+
55
+ def self.get_timer_message(start_time, time)
56
+ diff = time - start_time
57
+ avg = get_closest(diff)
58
+ amin, asec = get_time_parts(avg)
59
+ m, s = get_time_parts(diff)
60
+ colorize_if_should((avg == 0) ? "{#{m}:#{s}}(:time)" : get_avg_message(amin, asec, avg, diff, m, s))
61
+ end
62
+
63
+ def self.get_time_parts(time)
64
+ return (time / 60.0).floor, '%06.3f' % (time % 60)
65
+ end
66
+ end
@@ -0,0 +1,323 @@
1
+ require 'everyday-cli-utils'
2
+ include EverydayCliUtils
3
+ import :maputil
4
+
5
+ module Mvn2
6
+ class Plugins
7
+ def self.instance
8
+ @instance ||= Plugins.new
9
+ end
10
+
11
+ def initialize
12
+ @ext = {}
13
+ @types = {}
14
+ @vars = {}
15
+ end
16
+
17
+ def register(type, options = {}, &block)
18
+ @ext[type] ||= []
19
+ @ext[type] << { options: options, block: block }
20
+ end
21
+
22
+ def register_type(type, &block)
23
+ @types[type] = block
24
+ end
25
+
26
+ def register_variable(name, value = nil)
27
+ @vars[name] = value
28
+ end
29
+
30
+ def [](type)
31
+ @ext[type] || []
32
+ end
33
+
34
+ def get(type, *args)
35
+ @types[type].call(self[type], *args)
36
+ end
37
+
38
+ def self.get(type, *args)
39
+ instance.get(type, *args)
40
+ end
41
+
42
+ def get_var(name)
43
+ @vars[name] || nil
44
+ end
45
+
46
+ def set_var(name, value)
47
+ @vars[name] = value
48
+ end
49
+
50
+ def self.get_var(name)
51
+ instance.get_var(name)
52
+ end
53
+
54
+ def self.set_var(name, value)
55
+ instance.set_var(name, value)
56
+ end
57
+ end
58
+ module Plugin
59
+ def register(type, options = {}, &block)
60
+ Mvn2::Plugins.instance.register(type, options, &block)
61
+ end
62
+ end
63
+ module PluginType
64
+ def register_type(type, &block)
65
+ Mvn2::Plugins.instance.register_type(type, &block)
66
+ end
67
+
68
+ def register_variable(name, value = nil)
69
+ Mvn2::Plugins.instance.register_variable(name, value)
70
+ end
71
+ end
72
+ class DefaultTypes
73
+ extend Mvn2::PluginType
74
+
75
+ register_variable :options
76
+ register_variable :result
77
+ register_variable :runner
78
+ register_variable :cmd
79
+ register_variable :cmd_clean
80
+ register_variable :message_text
81
+
82
+ register_type(:option) { |list, options|
83
+ list.sort_by { |v| v[:options][:sym].to_s }.each { |option|
84
+ id = option[:options].delete(:sym)
85
+ names = option[:options].delete(:names)
86
+ default = option[:options].delete(:default) || nil
87
+ options.option id, names, option[:options]
88
+ options.default_options id => default unless default.nil?
89
+ }
90
+ }
91
+
92
+ register_type(:option_with_param) { |list, options|
93
+ list.sort_by { |v| v[:options][:sym].to_s }.each { |option|
94
+ id = option[:options].delete(:sym)
95
+ names = option[:options].delete(:names)
96
+ default = option[:options].delete(:default) || nil
97
+ options.option_with_param id, names, option[:options]
98
+ options.default_options id => default unless default.nil?
99
+ }
100
+ }
101
+
102
+ register_type(:command_flag) { |list|
103
+ options = Mvn2::Plugins.get_var :options
104
+ flags = []
105
+ list.each { |flag|
106
+ if flag[:block].nil?
107
+ flags << " #{flag[:options][:flag]}" if flag[:options].has_key?(:option) && options[flag[:options][:option]] == (flag[:options].has_key?(:value) ? flag[:options][:value] : true)
108
+ else
109
+ flag[:block].call(options, flags)
110
+ end
111
+ }
112
+ flags.join
113
+ }
114
+
115
+ register_type(:before_run) { |list|
116
+ options = Mvn2::Plugins.get_var :options
117
+ list.sort_by { |v| v[:options][:order] }.each { |item| item[:block].call(options) }
118
+ }
119
+
120
+ register_type(:after_run) { |list|
121
+ options = Mvn2::Plugins.get_var :options
122
+ result = Mvn2::Plugins.get_var :result
123
+ list.sort_by { |v| v[:options][:order] }.each { |item| item[:block].call(options, result) }
124
+ }
125
+
126
+ register_type(:before_start) { |list|
127
+ options = Mvn2::Plugins.get_var :options
128
+ list.sort_by { |v| v[:options][:order] }.each { |item| item[:block].call(options) }
129
+ }
130
+
131
+ register_type(:after_end) { |list|
132
+ options = Mvn2::Plugins.get_var :options
133
+ result = Mvn2::Plugins.get_var :result
134
+ list.sort_by { |v| v[:options][:order] }.each { |item| item[:block].call(options, result) }
135
+ }
136
+
137
+ register_type(:notification) { |list|
138
+ options = Mvn2::Plugins.get_var :options
139
+ result = Mvn2::Plugins.get_var :result
140
+ cmd_clean = Mvn2::Plugins.get_var :cmd_clean
141
+ message_text = Mvn2::Plugins.get_var :message_text
142
+ list.sort_by { |v| v[:options][:order] }.each { |item| item[:block].call(options, result, cmd_clean, message_text) }
143
+ }
144
+
145
+ register_type(:log_file_name) { |list|
146
+ options = Mvn2::Plugins.get_var :options
147
+ name = nil
148
+ list.sort_by { |v| -v[:options][:priority] }.each { |item|
149
+ if item[:block].nil?
150
+ if item[:options].has_key?(:name) && item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
151
+ name = item[:options][:name]
152
+ break
153
+ elsif item[:options].has_key?(:option) && !options[item[:options][:option]].nil?
154
+ name = options[item[:options][:option]]
155
+ break
156
+ end
157
+ else
158
+ rval = item[:block].call(options)
159
+ unless rval.nil?
160
+ name = rval
161
+ break
162
+ end
163
+ end
164
+ }
165
+ name
166
+ }
167
+
168
+ register_type(:log_file_disable) { |list|
169
+ options = Mvn2::Plugins.get_var :options
170
+ list.any? { |item|
171
+ if item[:block].nil?
172
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
173
+ else
174
+ item[:block].call(options)
175
+ end
176
+ }
177
+ }
178
+
179
+ register_type(:log_file_enable) { |list|
180
+ if Mvn2::Plugins.get(:log_file_name).nil? || Mvn2::Plugins.get(:log_file_disable)
181
+ false
182
+ else
183
+ options = Mvn2::Plugins.get_var :options
184
+ list.any? { |item|
185
+ if item[:block].nil?
186
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
187
+ else
188
+ item[:block].call(options)
189
+ end
190
+ }
191
+ end
192
+ }
193
+
194
+ register_type(:line_filter) { |list, line|
195
+ options = Mvn2::Plugins.get_var :options
196
+ line = line.chomp
197
+ result = nil
198
+ begin
199
+ list.sort_by { |v| -v[:options][:priority] }.each { |item|
200
+ tmp = item[:block].call(options, line)
201
+ unless tmp.nil?
202
+ result = tmp || nil
203
+ break
204
+ end
205
+ }
206
+ rescue
207
+ result = line
208
+ end
209
+ result
210
+ }
211
+
212
+ register_type(:runner_enable) { |list, key|
213
+ options = Mvn2::Plugins.get_var :options
214
+ list.select { |v| v[:options][:key] == key }.any? { |item|
215
+ if item[:block].nil?
216
+ item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
217
+ else
218
+ item[:block].call(options)
219
+ end
220
+ }
221
+ }
222
+
223
+ register_type(:runner) { |list|
224
+ options = Mvn2::Plugins.get_var :options
225
+ cmd = Mvn2::Plugins.get_var :cmd
226
+ Mvn2::Plugins.set_var :result, false
227
+ list.sort_by { |v| -v[:options][:priority] }.each { |item|
228
+ if Mvn2::Plugins.get(:runner_enable, item[:options][:key])
229
+ Mvn2::Plugins.set_var :runner, item[:options][:key]
230
+ Mvn2::Plugins.set_var :result, item[:block].call(options, cmd)
231
+ break
232
+ end
233
+ }
234
+ Mvn2::Plugins.get_var :result
235
+ }
236
+
237
+ register_type(:goal_override) { |list|
238
+ options = Mvn2::Plugins.get_var :options
239
+ full_overrides = list.select { |v| v[:options][:override_all] }.sort_by { |v| -v[:options][:priority] }.filtermap { |item|
240
+ if item[:block].nil?
241
+ if item[:options].has_key?(:goal) && item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
242
+ item[:options][:goal]
243
+ else
244
+ item[:options].has_key?(:option) && !options[item[:options][:option]].nil? ? options[item[:options][:option]] : false
245
+ end
246
+ else
247
+ rval = item[:block].call(options)
248
+ (rval.nil? || !rval) ? false : rval
249
+ end
250
+ }
251
+ if full_overrides.nil? || full_overrides.empty?
252
+ goals = list.select { |v| !v[:options][:override_all] }.sort_by { |v| v[:options][:order] }.filtermap { |item|
253
+ if item[:block].nil?
254
+ if item[:options].has_key?(:goal) && item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
255
+ item[:options][:goal]
256
+ else
257
+ item[:options].has_key?(:option) && !options[item[:options][:option]].nil? ? options[item[:options][:option]] : false
258
+ end
259
+ else
260
+ rval = item[:block].call(options)
261
+ (rval.nil? || !rval) ? false : rval
262
+ end
263
+ }
264
+ goals = ['install'] if (goals - ['clean']).empty?
265
+ goals = ['clean'] + goals unless goals.include?('clean')
266
+ goals.join(' ')
267
+ else
268
+ full_overrides.first
269
+ end
270
+ }
271
+
272
+ register_type(:operation_name) { |list|
273
+ options = Mvn2::Plugins.get_var :options
274
+ name = false
275
+ list.sort_by { |v| -v[:options][:priority] }.each { |item|
276
+ if item[:block].nil?
277
+ if item[:options].has_key?(:name) && item[:options].has_key?(:option) && options[item[:options][:option]] == (item[:options].has_key?(:value) ? item[:options][:value] : true)
278
+ name = item[:options][:name]
279
+ break
280
+ elsif item[:options].has_key?(:option) && !options[item[:options][:option]].nil?
281
+ name = options[item[:options][:option]]
282
+ break
283
+ end
284
+ else
285
+ rval = item[:block].call(options)
286
+ unless rval.nil? || !rval
287
+ name = rval
288
+ break
289
+ end
290
+ end
291
+ }
292
+ name || 'Operation'
293
+ }
294
+
295
+ DEFAULT_COLOR_OPTS = {
296
+ time: {
297
+ fg: :green,
298
+ bg: :none,
299
+ },
300
+ percent: {
301
+ fg: :purple,
302
+ bg: :none,
303
+ },
304
+ average: {
305
+ fg: :cyan,
306
+ bg: :none,
307
+ },
308
+ }
309
+
310
+ register_type(:color_override) { |list|
311
+ options = Mvn2::Plugins.get_var :options
312
+ opts = DEFAULT_COLOR_OPTS
313
+ list.sort_by { |v| -v[:options][:priority] }.each { |item|
314
+ rval = item[:block].call(options)
315
+ unless rval.nil? || !rval
316
+ opts = rval
317
+ break
318
+ end
319
+ }
320
+ opts.each { |opt| Format.color_profile opt[0], fgcolor: opt[1][:fg], bgcolor: opt[1][:bg] }
321
+ }
322
+ end
323
+ end
@@ -0,0 +1,3 @@
1
+ module Mvn2
2
+ VERSION = '2.0.0'
3
+ end
data/lib/mvn2.rb ADDED
@@ -0,0 +1 @@
1
+ require 'mvn2/version'
data/mvn2.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ #noinspection RubyResolve
5
+ require 'mvn2/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'mvn2'
9
+ spec.version = Mvn2::VERSION
10
+ spec.authors = ['Eric Henderson']
11
+ spec.email = ['henderea@gmail.com']
12
+ spec.summary = %q{Maven helper}
13
+ spec.description = %q{a Ruby script that runs a maven build, including (or not including) tests, and only outputs the lines that come after a compile failure, build success, test result, or reactor summary start line}
14
+ spec.homepage = 'https://github.com/henderea/mvn2'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.5'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+
25
+ spec.add_dependency 'everyday-cli-utils', '>= 1.3.0'
26
+ spec.add_dependency 'colorconfig', '>= 1.0.0'
27
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mvn2
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Eric Henderson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: everyday-cli-utils
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorconfig
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.0
69
+ description: a Ruby script that runs a maven build, including (or not including) tests,
70
+ and only outputs the lines that come after a compile failure, build success, test
71
+ result, or reactor summary start line
72
+ email:
73
+ - henderea@gmail.com
74
+ executables:
75
+ - mvn2
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/mvn2
85
+ - lib/mvn2.rb
86
+ - lib/mvn2/plugin.rb
87
+ - lib/mvn2/plugin/avg.plugin.rb
88
+ - lib/mvn2/plugin/command.plugin.rb
89
+ - lib/mvn2/plugin/default_runner.plugin.rb
90
+ - lib/mvn2/plugin/exception.plugin.rb
91
+ - lib/mvn2/plugin/filter.plugin.rb
92
+ - lib/mvn2/plugin/growl.plugin.rb
93
+ - lib/mvn2/plugin/live_print.plugin.rb
94
+ - lib/mvn2/plugin/logging.plugin.rb
95
+ - lib/mvn2/plugin/skip_tests.plugin.rb
96
+ - lib/mvn2/plugin/timer.plugin.rb
97
+ - lib/mvn2/version.rb
98
+ - mvn2.gemspec
99
+ homepage: https://github.com/henderea/mvn2
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.2.0
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Maven helper
123
+ test_files: []
124
+ has_rdoc: