git_manager 0.0.9 → 0.1.0

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.
data/config/email.yml CHANGED
@@ -1,7 +1,16 @@
1
1
  # example:
2
- # email_config:
2
+ # authentication:
3
3
  # from: you@yourdomain.com
4
4
  # password: your_password_here
5
5
  # users:
6
6
  # "User 1 Full Name as found in git blame":"associated_email1@domain.com@"
7
7
  # "User 2 Full Name as found in git blame":"associated_email2@domain.com@"
8
+ authentication:
9
+ from: you@your_gmail_hosted_domain.com
10
+ password: your_password_here
11
+
12
+ users:
13
+ 'First Name': 'me@my_gmail_hosted_domain.com'
14
+ 'First Name': 'me@my_gmail_hosted_domain.com'
15
+ 'First Name': 'me@my_gmail_hosted_domain.com'
16
+ 'First Name': 'me@my_gmail_hosted_domain.com'
data/lib/blames.rb ADDED
@@ -0,0 +1,43 @@
1
+ module Git::Blames
2
+ include Git::Emails
3
+
4
+ def blame(options = nil)
5
+ if !options[:spam]
6
+ self.tasks_by_collaborator.each_pair do |recipient, message|
7
+ send_gmail(
8
+ :recipients => [recipient],
9
+ :subject => "Please collaborate to fix consolidated list of specs: ",
10
+ :message => message
11
+ )
12
+ end
13
+ else
14
+ self.tasks.each_pair do |key, attributes|
15
+ if options.nil? || !options[:email]
16
+ stdout key, attributes
17
+ else
18
+ send_gmail :recipients => attributes[:contributors],
19
+ :subject => "Please collaborate to fix spec: " +
20
+ "#{attributes[:spec_file]} : " +
21
+ "#{attributes[:line_number]}",
22
+ :message => "Spec Details:\n " +
23
+ "Details\n #{attributes[:details].join('\n')}\n" +
24
+ "Collaborators:\n #{attributes[:contributors].join(', ')}\n"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def stdout key, attributes
31
+ puts "\nPending Spec Information:"
32
+ puts " Description: #{key}"
33
+ puts " Contributors: #{attributes[:contributors].join(', ')}"
34
+ puts " File: #{attributes[:spec_file]}"
35
+ puts " Line: #{attributes[:line_number]}\n"
36
+ end
37
+
38
+ # class Pending
39
+ # end
40
+
41
+ # class Blame
42
+ # end
43
+ end
@@ -0,0 +1,148 @@
1
+ class Git::Blames::Pending
2
+ attr_accessor :tasks, :rspec_results
3
+
4
+ include Git::Blames
5
+
6
+ def initialize options = nil
7
+ if options.nil? || options[:root].nil? && !options[:rspec] && !options[:log]
8
+ @root = "#{File.dirname(__FILE__)}/logs"
9
+ elsif options[:log]
10
+ find_pending_specs_by_logfile_name( options[:log] )
11
+ elsif options[:rspec]
12
+ find_pending_specs_by_rspec_results( rspec_results )
13
+ else
14
+ @root = options[:root]
15
+ find_pending_specs_by_logfile_name( "#{@root}/#{find_last_logfile_name}" )
16
+ end
17
+ find_contributors
18
+ end
19
+
20
+ def rspec_results
21
+ results = `rspec spec`
22
+ results
23
+ end
24
+
25
+ def find_contributors
26
+ # @tasks = Git::Blames::Pending.new.tasks
27
+ @tasks.each_pair do |key, attributes|
28
+ contributors = []
29
+ `git blame "#{attributes[:spec_file]}"`.each do |blame|
30
+ contributor = blame.split(")")[0].split("(")[1]
31
+ contributor = contributor.split(/\s+\d/)[0]
32
+ contributors.push( contributor )
33
+ end
34
+ @tasks[key][:contributors] = contributors.uniq
35
+ @tasks[key][:contributors].reject!{ |contributor| contributor == 'Not Committed Yet'}
36
+ end
37
+ @tasks
38
+ end
39
+
40
+ def found_pending_marker line
41
+ line.match( /^[\s\t]*Pending:/ )
42
+ end
43
+
44
+ def found_new_spec_marker line, status
45
+ ( status == 'start' || status == 'updating spec data' ) && !line.match( /^[\s\t]*#/ )
46
+ end
47
+
48
+ def found_spec_details_marker line, status
49
+ ( status == 'found new pending spec' || status == 'updating spec data' ) && line.match( /^[\s\t]*\#/ )
50
+ end
51
+
52
+ def find_last_logfile_name
53
+ begin
54
+ files = Dir.new @root
55
+ rescue => e
56
+ begin
57
+ Dir.mkdir @root
58
+ files = Dir.new @root
59
+ rescue
60
+ puts e
61
+ end
62
+ end
63
+ file_name = files.to_a.select { |log| log.match /\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/ }.sort.last
64
+ "#{file_name}/log"
65
+ end
66
+
67
+ def find_pending_specs_by_rspec_results spec_output
68
+ status = ''
69
+ @tasks = {}
70
+ task = {}
71
+
72
+ spec_output.each do |line|
73
+ if found_pending_marker line
74
+ status = 'start'
75
+
76
+ elsif found_new_spec_marker line, status
77
+ status = 'found new pending spec'
78
+ task = {}
79
+ task[:name] = line.chomp
80
+ task[:details] = []
81
+
82
+ elsif found_spec_details_marker line, status
83
+ status = 'updating spec data'
84
+ if line.match /(spec.*)[:](\d+)/
85
+ task[:spec_file] = $1
86
+ task[:line_number] = $2
87
+ else
88
+ task[:details].push line.chomp
89
+ end
90
+ @tasks[task[:name]] = task
91
+ end
92
+ end
93
+ end
94
+
95
+ def find_pending_specs_by_logfile_name logfile_name
96
+ logfile = File.new( logfile_name )
97
+ status = ''
98
+ @tasks = {}
99
+ task = {}
100
+
101
+ logfile.readlines.each do |line|
102
+
103
+ if found_pending_marker line
104
+ status = 'start'
105
+
106
+ elsif found_new_spec_marker line, status
107
+ status = 'found new pending spec'
108
+ task = {}
109
+ task[:name] = line.chomp
110
+ task[:details] = []
111
+
112
+ elsif found_spec_details_marker line, status
113
+ status = 'updating spec data'
114
+ if line.match /(spec.*)[:](\d+)/
115
+ task[:spec_file] = $1
116
+ task[:line_number] = $2
117
+ else
118
+ task[:details].push line.chomp
119
+ end
120
+ @tasks[task[:name]] = task
121
+ end
122
+ end
123
+ end
124
+
125
+ def tasks_by_collaborator
126
+ load_configuration
127
+ consolidated_emails = {}
128
+ @email_mappings.each_key do |contributor|
129
+ consolidated_emails[contributor] = []
130
+ @tasks.each do |object|
131
+ key = object[0]
132
+ values = object[1]
133
+ if values[:contributors].include?( contributor )
134
+ message = "\n" +
135
+ " Spec: #{values[:spec_file]}:#{values[:line_number]}\n" +
136
+ " Collaborators: #{values[:contributors].join(',')}\n" +
137
+ " Title: #{values[:name]}\n" +
138
+ " Details: #{values[:details].join('\n')}"
139
+ consolidated_emails[contributor].push( message )
140
+ end
141
+ end
142
+ consolidated_emails[contributor] = consolidated_emails[contributor].join(
143
+ "\n\n"
144
+ )
145
+ end
146
+ consolidated_emails
147
+ end
148
+ end
data/lib/emails.rb ADDED
@@ -0,0 +1,25 @@
1
+ module Git::Emails
2
+ def load_configuration
3
+ config = YAML::load_file( './config/email.yml' )
4
+ @email_from = config['authentication']['from']
5
+ @email_password = config['authentication']['password']
6
+ @email_mappings = config['users']
7
+ end
8
+
9
+ def send_gmail options
10
+ load_configuration
11
+ recipients = options[:recipients]
12
+ msg = "Subject: #{options[:subject]}\n\n#{options[:message]}"
13
+ smtp = Net::SMTP.new 'smtp.gmail.com', 587
14
+ smtp.enable_starttls
15
+ puts "Sending e-mail to #{recipients.join(',')}"
16
+ smtp.start( '', @email_from, @email_password, :login ) do
17
+ smtp.send_message( msg, @email_from, recipients.map{ |recipient|
18
+ # @email_mappings["#{recipient.gsub(' ', '_') }" ]
19
+ @email_mappings[ recipient ]
20
+ })
21
+ end
22
+ end
23
+ end
24
+
25
+
data/lib/git.rb ADDED
@@ -0,0 +1,2 @@
1
+ module Git
2
+ end
data/lib/git_manager.rb CHANGED
@@ -13,213 +13,11 @@
13
13
  require 'rubygems'
14
14
  require 'net/smtp'
15
15
  require 'yaml'
16
-
17
- module Git
18
- module Emails
19
- def load_configuration
20
- config = YAML::load_file('./config/email.yml')
21
- @email_from = config['authentication']['from']
22
- @email_password = config['authentication']['password']
23
- @email_mappings = config['users']
24
- puts "email_mappings = #{@email_mappings.inspect}"
25
- end
26
-
27
- def send_gmail options
28
- load_configuration
29
- recipients = options[:recipients]
30
- puts "recipients = #{recipients.inspect}"
31
- msg = "Subject: #{options[:subject]}\n\n#{options[:message]}"
32
- smtp = Net::SMTP.new 'smtp.gmail.com', 587
33
- smtp.enable_starttls
34
- smtp.start( '', @email_from, @email_password, :login ) do
35
- smtp.send_message( msg, @email_from, recipients.map{ |recipient| @email_mappings["#{recipient.gsub(' ', '_') }" ] } )
36
- end
37
- end
38
- end
39
-
40
- module Managed
41
- class Branch
42
- end
43
- end
44
-
45
- module Blames
46
- include Git::Emails
47
- def blame(options = nil)
48
- self.tasks.each_pair do |key, attributes|
49
- if options.nil? || !options[:email]
50
- stdout key, attributes
51
- else
52
- send_gmail :recipients => attributes[:contributors],
53
- :subject => "Please collaborate to fix spec: " +
54
- "#{attributes[:spec_file]} : " +
55
- "#{attributes[:line_number]}",
56
- :message => "Spec Details:\n " +
57
- "Details\n #{attributes[:details].join('\n')}\n" +
58
- "Collaborators:\n #{attributes[:contributors].join(', ')}\n"
59
- end
60
- end
61
- end
62
- def stdout key, attributes
63
- puts "\nPending Spec Information:"
64
- puts " Description: #{key}"
65
- puts " Contributors: #{attributes[:contributors].join(', ')}"
66
- puts " File: #{attributes[:spec_file]}"
67
- puts " Line: #{attributes[:line_number]}\n"
68
- end
69
- class Pending
70
- end
71
- class Blame
72
- end
73
- end
74
- end
75
-
76
- class Git::Managed::Branch
77
- attr_accessor :branches, :current_branch, :branches_to_delete
78
- def initialize
79
- @branches = `git branch`.split /\n/
80
- partition_branches
81
- end
82
- def partition_branches
83
- @current_branch = @branches.select {|branch| branch.match /^\*/}.first
84
- @branches_to_delete = @branches.select {|branch| branch != @current_branch }
85
- @current_branch.chomp!
86
- @current_branch.gsub! /\s|\*/, ''
87
- end
88
-
89
- def delete_branches
90
- return false if @branches_to_delete.length == 0
91
- @branches_to_delete.each do |branch|
92
- delete_branch( branch.gsub /\s/, '' )
93
- end
94
- end
95
-
96
- def delete_branch branch
97
- `git branch -D #{branch}`
98
- end
99
-
100
- end
101
-
102
- class Git::Blames::Pending
103
- attr_accessor :tasks, :rspec_results
104
-
105
- include Git::Blames
106
-
107
- def initialize options = nil
108
- if options.nil? || options[:root].nil? && !options[:rspec] && !options[:log]
109
- @root = "#{File.dirname(__FILE__)}/logs"
110
- elsif options[:log]
111
- find_pending_specs_by_logfile_name( options[:log] )
112
- elsif options[:rspec]
113
- find_pending_specs_by_rspec_results( rspec_results )
114
- else
115
- @root = options[:root]
116
- find_pending_specs_by_logfile_name( "#{@root}/#{find_last_logfile_name}" )
117
- end
118
- find_contributors
119
- end
120
-
121
- def rspec_results
122
- results = `rspec spec`
123
- results
124
- end
125
-
126
- def find_contributors
127
- # @tasks = Git::Blames::Pending.new.tasks
128
- @tasks.each_pair do |key, attributes|
129
- contributors = []
130
- `git blame "#{attributes[:spec_file]}"`.each do |blame|
131
- contributor = blame.split(")")[0].split("(")[1]
132
- contributor = contributor.split(/\s+\d/)[0]
133
- contributors.push( contributor )
134
- end
135
- @tasks[key][:contributors] = contributors.uniq
136
- @tasks[key][:contributors].reject!{ |contributor| contributor == 'Not Committed Yet'}
137
- end
138
- @tasks
139
- end
140
-
141
- def found_pending_marker line
142
- line.match( /^[\s\t]*Pending:/ )
143
- end
144
-
145
- def found_new_spec_marker line, status
146
- ( status == 'start' || status == 'updating spec data' ) && !line.match( /^[\s\t]*#/ )
147
- end
148
-
149
- def found_spec_details_marker line, status
150
- ( status == 'found new pending spec' || status == 'updating spec data' ) && line.match( /^[\s\t]*\#/ )
151
- end
152
-
153
- def find_last_logfile_name
154
- begin
155
- files = Dir.new @root
156
- rescue => e
157
- begin
158
- Dir.mkdir @root
159
- files = Dir.new @root
160
- rescue
161
- puts e
162
- end
163
- end
164
- file_name = files.to_a.select { |log| log.match /\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/ }.sort.last
165
- "#{file_name}/log"
166
- end
167
-
168
- def find_pending_specs_by_rspec_results spec_output
169
- status = ''
170
- @tasks = {}
171
- task = {}
172
-
173
- spec_output.each do |line|
174
- if found_pending_marker line
175
- status = 'start'
176
-
177
- elsif found_new_spec_marker line, status
178
- status = 'found new pending spec'
179
- task = {}
180
- task[:name] = line.chomp
181
- task[:details] = []
182
-
183
- elsif found_spec_details_marker line, status
184
- status = 'updating spec data'
185
- if line.match /(spec.*)[:](\d+)/
186
- task[:spec_file] = $1
187
- task[:line_number] = $2
188
- else
189
- task[:details].push line.chomp
190
- end
191
- @tasks[task[:name]] = task
192
- end
193
- end
194
- end
195
-
196
- def find_pending_specs_by_logfile_name logfile_name
197
- logfile = File.new( logfile_name )
198
- status = ''
199
- @tasks = {}
200
- task = {}
201
-
202
- logfile.readlines.each do |line|
203
-
204
- if found_pending_marker line
205
- status = 'start'
206
-
207
- elsif found_new_spec_marker line, status
208
- status = 'found new pending spec'
209
- task = {}
210
- task[:name] = line.chomp
211
- task[:details] = []
212
-
213
- elsif found_spec_details_marker line, status
214
- status = 'updating spec data'
215
- if line.match /(spec.*)[:](\d+)/
216
- task[:spec_file] = $1
217
- task[:line_number] = $2
218
- else
219
- task[:details].push line.chomp
220
- end
221
- @tasks[task[:name]] = task
222
- end
223
- end
224
- end
225
- end
16
+ require "#{ File.dirname( __FILE__ ) }/git"
17
+ require "#{ File.dirname( __FILE__ ) }/managed"
18
+ require "#{ File.dirname( __FILE__ ) }/managed/branch"
19
+ require "#{ File.dirname( __FILE__ ) }/emails"
20
+ require "#{ File.dirname( __FILE__ ) }/blames"
21
+ require "#{ File.dirname( __FILE__ ) }/blames/pending"
22
+
23
+ Git::Blames::Pending.new( :root => './lib/logs/' ).blame( :email => true )
data/lib/managed.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Git::Managed
2
+ class Branch
3
+ end
4
+ end
@@ -0,0 +1,27 @@
1
+ class Git::Managed::Branch
2
+ attr_accessor :branches, :current_branch, :branches_to_delete
3
+
4
+ def initialize
5
+ @branches = `git branch`.split /\n/
6
+ partition_branches
7
+ end
8
+
9
+ def partition_branches
10
+ @current_branch = @branches.select {|branch| branch.match /^\*/}.first
11
+ @branches_to_delete = @branches.select {|branch| branch != @current_branch }
12
+ @current_branch.chomp!
13
+ @current_branch.gsub! /\s|\*/, ''
14
+ end
15
+
16
+ def delete_branches
17
+ return false if @branches_to_delete.length == 0
18
+ @branches_to_delete.each do |branch|
19
+ delete_branch( branch.gsub /\s/, '' )
20
+ end
21
+ end
22
+
23
+ def delete_branch branch
24
+ `git branch -D #{branch}`
25
+ end
26
+
27
+ end
@@ -80,5 +80,36 @@ describe Git do
80
80
  @git_blames_pending.tasks[@test_01][:details].should == @expected_tasks[@test_01][:details]
81
81
  @git_blames_pending.tasks[@test_02][:details].should == @expected_tasks[@test_02][:details]
82
82
  end
83
+
84
+ it "consolidates blames into structure for e-mailing each developer once" do
85
+
86
+ expected_text = "\n" +
87
+ " Spec: spec/git_manager_spec.rb:11\n" +
88
+ " Collaborators: John Jimenez\n" +
89
+ " Title: Fake test 2 spec/git_manager_spec.rb\n" +
90
+ " Details: # Test 123\n\n\n" +
91
+ " Spec: spec/git_manager_spec.rb:13\n" +
92
+ " Collaborators: John Jimenez\n" +
93
+ " Title: Fake test 1 spec/git_manager_spec.rb\n" +
94
+ " Details: # Test 123"
95
+
96
+ @git_blames_pending.tasks_by_collaborator.should == {
97
+ "John Jimenez" => expected_text
98
+ }
99
+ # { " Fake test 2 spec/git_manager_spec.rb"=>{
100
+ # :spec_file=>"spec/git_manager_spec.rb",
101
+ # :details=>[" # Test 123"],
102
+ # :contributors=>["John Jimenez"],
103
+ # :name=>" Fake test 2 spec/git_manager_spec.rb",
104
+ # :line_number=>"11"
105
+ # },
106
+ # " Fake test 1 spec/git_manager_spec.rb"=>{
107
+ # :spec_file=>"spec/git_manager_spec.rb",
108
+ # :details=>[" # Test 123"],
109
+ # :contributors=>["John Jimenez"],
110
+ # :name=>" Fake test 1 spec/git_manager_spec.rb",
111
+ # :line_number=>"13"
112
+ # }
113
+ end
83
114
  end
84
115
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_manager
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 9
10
- version: 0.0.9
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - kikuchiyo
@@ -15,14 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-08-22 00:00:00 Z
18
+ date: 2012-10-31 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
- description: |-
22
- delete old git branches and blame pending specs
23
- for e-mailing: requires config/email.yml file in root directory
24
- for using build logs make sure you pass path to Git::Blames::Pending.new through :root parameter. Bug fix to contributors - was not being reset per spec
25
- email: kikuchiyo6@gmail.com
21
+ description: A QA Automation Enineer's Assistant, utilizing Jenkins and Git.
22
+ email: jimenez.john0@gmail.com
26
23
  executables: []
27
24
 
28
25
  extensions: []
@@ -30,9 +27,15 @@ extensions: []
30
27
  extra_rdoc_files: []
31
28
 
32
29
  files:
33
- - lib/git_manager.rb
34
30
  - lib/logs/2012-08-21_00-00-02/log
31
+ - lib/blames/pending.rb
32
+ - lib/managed/branch.rb
33
+ - lib/git_manager.rb
35
34
  - config/email.yml
35
+ - lib/managed.rb
36
+ - lib/blames.rb
37
+ - lib/emails.rb
38
+ - lib/git.rb
36
39
  - spec/git_manager_spec.rb
37
40
  homepage: http://rubygems.org/gems/git_manager
38
41
  licenses: []
@@ -63,9 +66,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
66
  requirements: []
64
67
 
65
68
  rubyforge_project:
66
- rubygems_version: 1.8.24
69
+ rubygems_version: 1.8.10
67
70
  signing_key:
68
71
  specification_version: 3
69
- summary: gem to manage git
72
+ summary: qa automation engineer assistant
70
73
  test_files:
71
74
  - spec/git_manager_spec.rb
75
+ has_rdoc: