xing-cap_gun 0.3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/CHANGELOG +27 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.markdown +111 -0
- data/Rakefile +16 -0
- data/cap_gun.gemspec +22 -0
- data/lib/cap_gun/presenter.rb +146 -0
- data/lib/cap_gun.rb +80 -0
- data/spec/cap_gun_spec.rb +57 -0
- data/spec/presenter_spec.rb +128 -0
- data/spec/spec_helper.rb +8 -0
- metadata +154 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
v0.2.4 Clean up and a little more safety around previous revision
|
2
|
+
|
3
|
+
v0.2.3 Fix the case where there is no previous revision so it doesn't blow up
|
4
|
+
|
5
|
+
v0.2.2 SVN support courtesy Olivier Brisse
|
6
|
+
|
7
|
+
v0.2.1 Documentation update so that it works with ActionMailer 2.3+
|
8
|
+
|
9
|
+
v0.2.0 Git changes in the email, major refactoring
|
10
|
+
|
11
|
+
v0.0.9 Ruby 1.8.7 support via a small change to the Net::SMTP SSL hack
|
12
|
+
|
13
|
+
v0.0.8. Fix failing spec on runcoderun that depended on timezone; add redgreen to specs
|
14
|
+
|
15
|
+
v0.0.7. Pick up changelog and gemspec
|
16
|
+
|
17
|
+
v0.0.6. Fix subject line if there *is* a rails_env defined - this was a bug introduced with the 0.0.5 'fix'. Awesome.
|
18
|
+
|
19
|
+
v0.0.5. Fix subject line iv there is no rails_env defined
|
20
|
+
|
21
|
+
v0.0.4. Add dev dependency on echoe; update manifest
|
22
|
+
|
23
|
+
v0.0.3. Don't try to convert the RAILS_ENV if its not set to better support default capistrano deployments
|
24
|
+
|
25
|
+
v0.0.2. Converts the release times to the current time zone; improved docs.
|
26
|
+
|
27
|
+
v0.0.1. Initial release. Rock n roll mcdonalds.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Relevance, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# CapGun
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Tell everyone about your releases! Send email notification after Capistrano deployments! Rule the world!
|
6
|
+
|
7
|
+
Drop your ActionMailer configuration information into your deploy.rb file, configure recipients for the deployment notifications, and setup the callback task.
|
8
|
+
|
9
|
+
Setup and configuration are done entirely inside your deploy.rb file to keep it super simple. Your emails are sent locally from the box performing the deployment, but CapGun queries the server to grab the necessary release info.
|
10
|
+
|
11
|
+
## Config
|
12
|
+
|
13
|
+
In your Capistrano config file (usually `deploy.rb`):
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require "cap_gun"
|
17
|
+
|
18
|
+
# setup action mailer (if not done in rails environment already)
|
19
|
+
ActionMailer::Base.smtp_settings = {
|
20
|
+
:address => "smtp.gmail.com",
|
21
|
+
:port => 587,
|
22
|
+
:domain => "example.com",
|
23
|
+
:user_name => "<username>",
|
24
|
+
:password => "<password>",
|
25
|
+
:authentication => "plain",
|
26
|
+
:enable_starttls_auto => true
|
27
|
+
}
|
28
|
+
|
29
|
+
# define a repository url to provide a link in the email (optional)
|
30
|
+
set :repository_url, "https://github.com/example/my-project"
|
31
|
+
|
32
|
+
# define the options for the actual emails that go out -- :recipients is the only required option
|
33
|
+
set :cap_gun_email_envelope, {
|
34
|
+
:recipients => %w[joe@example.com, jane@example.com],
|
35
|
+
:from => "project.deployer@example.com"
|
36
|
+
}
|
37
|
+
|
38
|
+
# register email as a callback after restart
|
39
|
+
after "deploy:restart", "cap_gun:email"
|
40
|
+
```
|
41
|
+
|
42
|
+
Test everything out by running `cap cap_gun:email`.
|
43
|
+
|
44
|
+
## Usage
|
45
|
+
|
46
|
+
Good news: it just works.
|
47
|
+
|
48
|
+
By default CapGun includes info like the user who is deploying and what server its being deployed to. CapGun is biased for git (patches accepted for other SCMs), so it will include details like your current branch, the revisions since last deployment, the current commit being deployed.
|
49
|
+
|
50
|
+
Want to make the notifications even better and explain _why_ you're deploying?
|
51
|
+
Just include a comment in the cap command like so, and CapGun will add the comment to the email notification.
|
52
|
+
|
53
|
+
$ cap -s comment="fix for bug #303" deploy
|
54
|
+
|
55
|
+
## Requirements
|
56
|
+
|
57
|
+
* Capistrano 2+
|
58
|
+
* SMTP server or MTA (mail transport agent) installed locally to send from
|
59
|
+
* Something to deploy
|
60
|
+
|
61
|
+
## Todo & Known Issues
|
62
|
+
|
63
|
+
* displays the release times in UTC (Capistrano default) - could be flipped to specified time zone
|
64
|
+
* some stuff will probably break on windows - patches welcome
|
65
|
+
|
66
|
+
## Install
|
67
|
+
|
68
|
+
Add this line to your application's `Gemfile`:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
gem "cap_gun"
|
72
|
+
```
|
73
|
+
|
74
|
+
And then execute:
|
75
|
+
|
76
|
+
$ bundle
|
77
|
+
|
78
|
+
Or install it manually:
|
79
|
+
|
80
|
+
$ gem install cap_gun
|
81
|
+
|
82
|
+
## URLs
|
83
|
+
|
84
|
+
* Log bugs, issues, and suggestions at GitHub: http://github.com/relevance/cap_gun/issues
|
85
|
+
* View source: http://github.com/relevance/cap_gun
|
86
|
+
* SDocs: http://relevance.github.com/cap_gun/
|
87
|
+
|
88
|
+
## License
|
89
|
+
|
90
|
+
(The MIT License)
|
91
|
+
|
92
|
+
Copyright (c) 2009 Relevance, Inc. - http://thinkrelevance.com
|
93
|
+
|
94
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
95
|
+
a copy of this software and associated documentation files (the
|
96
|
+
'Software'), to deal in the Software without restriction, including
|
97
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
98
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
99
|
+
permit persons to whom the Software is furnished to do so, subject to
|
100
|
+
the following conditions:
|
101
|
+
|
102
|
+
The above copyright notice and this permission notice shall be
|
103
|
+
included in all copies or substantial portions of the Software.
|
104
|
+
|
105
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
106
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
107
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
108
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
109
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
110
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
111
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rdoc/task"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
|
5
|
+
Rake::RDocTask.new do |t|
|
6
|
+
t.title = "cap_gun"
|
7
|
+
t.rdoc_dir = "rdoc"
|
8
|
+
t.rdoc_files.include("README*")
|
9
|
+
t.rdoc_files.include("lib/**/*.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new do |t|
|
13
|
+
t.rspec_opts = "--color"
|
14
|
+
end
|
15
|
+
|
16
|
+
task :default => :spec
|
data/cap_gun.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |gem|
|
3
|
+
gem.authors = ["Sebastian Röbke", "Rob Sanheim", "Muness Alrubaie", "Relevance"]
|
4
|
+
gem.email = ["sebastian.roebke@xing.com"]
|
5
|
+
gem.description = %q{Super simple capistrano deployment notifications. Forked from relevance/cap_gun.}
|
6
|
+
gem.summary = %q{Super simple capistrano deployment notifications. Forked from relevance/cap_gun.}
|
7
|
+
gem.homepage = "https://github.com/xing/cap_gun"
|
8
|
+
|
9
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
10
|
+
gem.files = `git ls-files`.split("\n")
|
11
|
+
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
12
|
+
gem.name = "xing-cap_gun"
|
13
|
+
gem.require_paths = ["lib"]
|
14
|
+
gem.version = "0.3.0.pre"
|
15
|
+
|
16
|
+
gem.add_dependency("activesupport")
|
17
|
+
gem.add_dependency("actionmailer", ">= 3.0.0")
|
18
|
+
|
19
|
+
gem.add_development_dependency("rake")
|
20
|
+
gem.add_development_dependency("rdoc")
|
21
|
+
gem.add_development_dependency("rspec")
|
22
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'etc'
|
2
|
+
|
3
|
+
module CapGun
|
4
|
+
class Presenter
|
5
|
+
DEFAULT_SENDER = %("CapGun" <cap_gun@example.com>)
|
6
|
+
DEFAULT_EMAIL_PREFIX = "[DEPLOY]"
|
7
|
+
|
8
|
+
attr_accessor :capistrano
|
9
|
+
|
10
|
+
def initialize(capistrano)
|
11
|
+
self.capistrano = capistrano
|
12
|
+
end
|
13
|
+
|
14
|
+
def recipients
|
15
|
+
capistrano[:cap_gun_email_envelope][:recipients]
|
16
|
+
end
|
17
|
+
|
18
|
+
def email_prefix
|
19
|
+
capistrano[:cap_gun_email_envelope][:email_prefix] || DEFAULT_EMAIL_PREFIX
|
20
|
+
end
|
21
|
+
|
22
|
+
def from
|
23
|
+
capistrano[:cap_gun_email_envelope][:from] || DEFAULT_SENDER
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_user
|
27
|
+
Etc.getlogin
|
28
|
+
end
|
29
|
+
|
30
|
+
def summary
|
31
|
+
%[#{capistrano[:application]} was #{deployed_to} by #{current_user} at #{release_time}.]
|
32
|
+
end
|
33
|
+
|
34
|
+
def deployed_to
|
35
|
+
return "deployed to #{capistrano[:rails_env]}" if capistrano[:rails_env]
|
36
|
+
"deployed"
|
37
|
+
end
|
38
|
+
|
39
|
+
def branch
|
40
|
+
"Branch: #{capistrano[:branch]}" unless capistrano[:branch].nil? || capistrano[:branch].empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def scm_details
|
44
|
+
return unless [:git,:subversion].include? capistrano[:scm].to_sym
|
45
|
+
<<-EOL
|
46
|
+
#{branch}
|
47
|
+
#{scm_log}
|
48
|
+
EOL
|
49
|
+
rescue
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def scm_log
|
54
|
+
"\nCommits since last release\n====================\n#{scm_log_messages}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def scm_log_messages
|
58
|
+
messages = case capistrano[:scm].to_sym
|
59
|
+
when :git
|
60
|
+
`git log #{previous_revision}..#{capistrano[:current_revision]} --pretty=format:%h:%s`
|
61
|
+
when :subversion
|
62
|
+
`svn log -r #{previous_revision.to_i+1}:#{capistrano[:current_revision]}`
|
63
|
+
else
|
64
|
+
"N/A"
|
65
|
+
end
|
66
|
+
exit_code.success? ? messages : "N/A"
|
67
|
+
end
|
68
|
+
|
69
|
+
def exit_code
|
70
|
+
$?
|
71
|
+
end
|
72
|
+
|
73
|
+
# Gives you a prettier date/time for output from the standard Capistrano timestamped release directory.
|
74
|
+
# This assumes Capistrano uses UTC for its date/timestamped directories, and converts to the local
|
75
|
+
# machine timezone.
|
76
|
+
def humanize_release_time(path)
|
77
|
+
return unless path
|
78
|
+
match = path.match(/(\d+)$/)
|
79
|
+
return unless match
|
80
|
+
local = convert_from_utc(match[1])
|
81
|
+
local.strftime("%B #{local.day.ordinalize}, %Y %l:%M %p #{local_timezone}").gsub(/\s+/, ' ').strip
|
82
|
+
end
|
83
|
+
|
84
|
+
# Use some DateTime magicrey to convert UTC to the current time zone
|
85
|
+
# When the whole world is on Rails 2.1 (and therefore new ActiveSupport) we can use the magic timezone support there.
|
86
|
+
def convert_from_utc(timestamp)
|
87
|
+
# we know Capistrano release timestamps are UTC, but Ruby doesn't, so make it explicit
|
88
|
+
utc_time = timestamp << "UTC"
|
89
|
+
datetime = DateTime.parse(utc_time)
|
90
|
+
datetime.new_offset(local_datetime_zone_offset)
|
91
|
+
end
|
92
|
+
|
93
|
+
def local_datetime_zone_offset
|
94
|
+
@local_datetime_zone_offset ||= DateTime.now.offset
|
95
|
+
end
|
96
|
+
|
97
|
+
def local_timezone
|
98
|
+
@current_timezone ||= Time.now.zone
|
99
|
+
end
|
100
|
+
|
101
|
+
def release_time
|
102
|
+
humanize_release_time(capistrano[:current_release])
|
103
|
+
end
|
104
|
+
|
105
|
+
def previous_revision
|
106
|
+
capistrano.fetch(:previous_revision, "n/a")
|
107
|
+
end
|
108
|
+
|
109
|
+
def previous_release_time
|
110
|
+
humanize_release_time(capistrano[:previous_release])
|
111
|
+
end
|
112
|
+
|
113
|
+
def subject
|
114
|
+
"#{email_prefix} #{capistrano[:application]} #{deployed_to}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def comment
|
118
|
+
"Comment: #{capistrano[:comment]}.\n" if capistrano[:comment]
|
119
|
+
end
|
120
|
+
|
121
|
+
def repository
|
122
|
+
capistrano[:repository_url] || capistrano[:repository]
|
123
|
+
end
|
124
|
+
|
125
|
+
def body
|
126
|
+
body = "#{summary}\n"
|
127
|
+
body << "#{comment}\n"
|
128
|
+
body << "Deployment details\n"
|
129
|
+
body << "====================\n"
|
130
|
+
body << "Release: #{capistrano[:current_release]}\n"
|
131
|
+
body << "Release Time: #{release_time}\n"
|
132
|
+
body << "Release Revision: #{capistrano[:current_revision]}\n"
|
133
|
+
body << "\n"
|
134
|
+
body << "Previous Release: #{capistrano[:previous_release]}\n"
|
135
|
+
body << "Previous Release Time: #{previous_release_time}\n"
|
136
|
+
body << "Previous Release Revision: #{previous_revision}\n"
|
137
|
+
body << "\n"
|
138
|
+
body << "Repository: #{repository}\n"
|
139
|
+
body << "Deploy path: #{capistrano[:deploy_to]}\n"
|
140
|
+
body << "Domain: #{capistrano[:domain]}\n" if capistrano[:domain]
|
141
|
+
body << "#{scm_details}\n"
|
142
|
+
body
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
data/lib/cap_gun.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
begin
|
4
|
+
# This requires the full active_support.
|
5
|
+
# ActiveSupport v3 and up are modular and
|
6
|
+
# need to be explicitly loaded.
|
7
|
+
# Rescue in cases of ActiveSupport 2.3.2 and earlier.
|
8
|
+
require 'active_support/all'
|
9
|
+
rescue
|
10
|
+
# Do nothing, everything should be included
|
11
|
+
# by default in older versions of ActiveSupport.
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'action_mailer'
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), *%w[cap_gun presenter])
|
17
|
+
|
18
|
+
# Tell everyone about your releases! Send email notification after Capistrano deployments! Rule the world!
|
19
|
+
#
|
20
|
+
# Example:
|
21
|
+
#
|
22
|
+
# Want to just shoot everyone an email about the latest status?
|
23
|
+
#
|
24
|
+
# cap cap_gun:email
|
25
|
+
#
|
26
|
+
# Include comments?
|
27
|
+
#
|
28
|
+
# cap -s comment="hi mom" cap_gun:email
|
29
|
+
#
|
30
|
+
# Enable emails after every deploy by adding this to your deploy.rb:
|
31
|
+
#
|
32
|
+
# after "deploy", "cap_gun:email"
|
33
|
+
#
|
34
|
+
# Now, next time you deploy, you can optionally include comments:
|
35
|
+
#
|
36
|
+
# cap -s comment="fix for bug #303" deploy
|
37
|
+
#
|
38
|
+
# See README for full install/config instructions.
|
39
|
+
module CapGun
|
40
|
+
# This mailer is configured with a capistrano variable called "cap_gun_email_envelope"
|
41
|
+
class Mailer < ActionMailer::Base
|
42
|
+
|
43
|
+
def self.load_mailer_config(cap)
|
44
|
+
raise ArgumentError, "Need at least one recipient." if !cap.exists?(:cap_gun_email_envelope) || cap[:cap_gun_email_envelope][:recipients].blank?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Grab the options for emailing from capistrano[:cap_gun_email_envelope] (should be set in your deploy file)
|
48
|
+
#
|
49
|
+
# Valid options:
|
50
|
+
# :recipients (required) an array or string of email address(es) that should get notifications
|
51
|
+
# :from the sender of the notification, defaults to cap_gun@example.com
|
52
|
+
# :email_prefix subject prefix, defaults to [DEPLOY]
|
53
|
+
def deployment_notification(capistrano)
|
54
|
+
presenter = Presenter.new(capistrano)
|
55
|
+
mail(
|
56
|
+
:from => presenter.from,
|
57
|
+
:to => presenter.recipients,
|
58
|
+
:subject => presenter.subject
|
59
|
+
) do |format|
|
60
|
+
format.text { render :text => presenter.body }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
if Object.const_defined?("Capistrano")
|
68
|
+
|
69
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
70
|
+
|
71
|
+
namespace :cap_gun do
|
72
|
+
desc "Send notification of the current release and the previous release via email."
|
73
|
+
task :email, :roles => :app do
|
74
|
+
CapGun::Mailer.load_mailer_config(self)
|
75
|
+
CapGun::Mailer.deployment_notification(self).deliver
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CapGun do
|
4
|
+
describe "mail settings" do
|
5
|
+
it "raises if don't have a cap gun email envelope" do
|
6
|
+
capistrano = double(
|
7
|
+
:cap_gun_action_mailer_config => {},
|
8
|
+
:exists? => false
|
9
|
+
).as_null_object
|
10
|
+
|
11
|
+
lambda {
|
12
|
+
CapGun::Mailer.load_mailer_config(capistrano)
|
13
|
+
}.should raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises if we don't have at least one recipient" do
|
17
|
+
capistrano = double(
|
18
|
+
:cap_gun_action_mailer_config => {},
|
19
|
+
:cap_gun_email_envelope => {}
|
20
|
+
).as_null_object
|
21
|
+
|
22
|
+
lambda {
|
23
|
+
CapGun::Mailer.load_mailer_config(capistrano)
|
24
|
+
}.should raise_error(ArgumentError)
|
25
|
+
|
26
|
+
capistrano = double(
|
27
|
+
:cap_gun_action_mailer_config => {},
|
28
|
+
:cap_gun_email_envelope => {
|
29
|
+
:recipients => []
|
30
|
+
}
|
31
|
+
).as_null_object
|
32
|
+
|
33
|
+
lambda {
|
34
|
+
CapGun::Mailer.load_mailer_config(capistrano)
|
35
|
+
}.should raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe CapGun::Mailer do
|
40
|
+
describe "deployment_notification" do
|
41
|
+
it "builds the correct mail object" do
|
42
|
+
capistrano = {
|
43
|
+
:cap_gun_email_envelope => {
|
44
|
+
:recipients => ["joe@example.com"],
|
45
|
+
:from => "me@example.com"
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
presenter = CapGun::Presenter.new(capistrano)
|
50
|
+
mail = CapGun::Mailer.deployment_notification(capistrano)
|
51
|
+
mail.to.should == presenter.recipients
|
52
|
+
mail.from.should == [presenter.from] # yes, Mail gem returns an array here
|
53
|
+
mail.subject.should == presenter.subject
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CapGun::Presenter do
|
4
|
+
|
5
|
+
describe "scm details" do
|
6
|
+
|
7
|
+
it "does nothing if the scm is not git nor subversion" do
|
8
|
+
presenter = CapGun::Presenter.new({:scm => :mercurial})
|
9
|
+
presenter.scm_details.should == nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "collects branch and git log details if git is scm" do
|
13
|
+
capistrano = {:scm => :git, :branch => "edge"}
|
14
|
+
presenter = CapGun::Presenter.new(capistrano)
|
15
|
+
presenter.should_receive(:scm_log).and_return("xxxxx")
|
16
|
+
|
17
|
+
details = presenter.scm_details
|
18
|
+
details.should include("Branch: edge")
|
19
|
+
details.should include("xxxxx")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "scm log messages" do
|
24
|
+
describe "with git" do
|
25
|
+
it "returns N/A if the git log call returns an error" do
|
26
|
+
capistrano = {:scm => :git, :previous_revision => "previous-sha", :current_revision => "current-sha" }
|
27
|
+
presenter = CapGun::Presenter.new(capistrano)
|
28
|
+
presenter.stub(:`).and_return("fatal: Not a git repo")
|
29
|
+
presenter.stub(:exit_code).and_return(stub("process status", :success? => false))
|
30
|
+
presenter.scm_log_messages.should == "N/A"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "calls git log with previous_rev..current_rev" do
|
34
|
+
capistrano = {:scm => :git, :previous_revision => "previous-sha", :current_revision => "current-sha" }
|
35
|
+
presenter = CapGun::Presenter.new(capistrano)
|
36
|
+
presenter.stub(:exit_code).and_return(stub("process status", :success? => true))
|
37
|
+
presenter.should_receive(:`).with(/git log previous-sha..current-sha/)
|
38
|
+
presenter.scm_log_messages
|
39
|
+
end
|
40
|
+
end
|
41
|
+
describe "with subversion" do
|
42
|
+
it "returns N/A if the svn log call returns an error" do
|
43
|
+
capistrano = {:scm => :subversion, :previous_revision => "42", :current_revision => "46" }
|
44
|
+
presenter = CapGun::Presenter.new(capistrano)
|
45
|
+
presenter.stub(:`).and_return("fatal: Not a working copy")
|
46
|
+
presenter.stub(:exit_code).and_return(stub("process status", :success? => false))
|
47
|
+
presenter.scm_log_messages.should == "N/A"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "calls svn log with -r previous_rev+1:current_rev" do
|
51
|
+
capistrano = {:scm => :subversion, :previous_revision => "42", :current_revision => "46" }
|
52
|
+
presenter = CapGun::Presenter.new(capistrano)
|
53
|
+
presenter.stub(:exit_code).and_return(stub("process status", :success? => true))
|
54
|
+
presenter.should_receive(:`).with(/svn log -r 43:46/)
|
55
|
+
presenter.scm_log_messages
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "release time" do
|
61
|
+
|
62
|
+
before do # make DateTime act as if local timezone is CDT
|
63
|
+
@presenter = CapGun::Presenter.new(nil)
|
64
|
+
@presenter.stub(:local_timezone).and_return("CDT")
|
65
|
+
@presenter.stub(:local_datetime_zone_offset).and_return(Rational(-1,6))
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns nil for weird release path" do
|
69
|
+
@presenter.humanize_release_time("/data/foo/my_release").should == nil
|
70
|
+
end
|
71
|
+
|
72
|
+
it "parse datetime from release path" do
|
73
|
+
@presenter.humanize_release_time("/data/foo/releases/20080227120000").should == "February 27th, 2008 8:00 AM CDT"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "converts time from release into localtime" do
|
77
|
+
@presenter.humanize_release_time("/data/foo/releases/20080410040000").should == "April 10th, 2008 12:00 AM CDT"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "from and to emails" do
|
83
|
+
|
84
|
+
it "gets recipients from email envelope" do
|
85
|
+
capistrano = { :cap_gun_email_envelope => { :recipients => ["foo@here.com", "bar@here.com"] } }
|
86
|
+
presenter = CapGun::Presenter.new(capistrano)
|
87
|
+
presenter.recipients.should == ["foo@here.com", "bar@here.com"]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have a default sender" do
|
91
|
+
capistrano = { :cap_gun_email_envelope => { } }
|
92
|
+
presenter = CapGun::Presenter.new(capistrano)
|
93
|
+
presenter.from.should == "\"CapGun\" <cap_gun@example.com>"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should override sender from email envelope" do
|
97
|
+
capistrano = { :cap_gun_email_envelope => { :from => "booyakka!@example.com" } }
|
98
|
+
presenter = CapGun::Presenter.new(capistrano)
|
99
|
+
presenter.from.should == "booyakka!@example.com"
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "previous_revision" do
|
105
|
+
|
106
|
+
it "returns n/a if not set" do
|
107
|
+
CapGun::Presenter.new({}).previous_revision.should == "n/a"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns the previous revision if set" do
|
111
|
+
CapGun::Presenter.new({:previous_revision => "100"}).previous_revision.should == "100"
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "repository" do
|
117
|
+
|
118
|
+
it "returns the :repository_url variable if set" do
|
119
|
+
CapGun::Presenter.new({:repository_url => "foo"}).repository.should == "foo"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "returns the :repository variable otherwise" do
|
123
|
+
CapGun::Presenter.new({:repository => "bar"}).repository.should == "bar"
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xing-cap_gun
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 1030634103
|
5
|
+
prerelease: 6
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
- pre
|
11
|
+
version: 0.3.0.pre
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- "Sebastian R\xC3\xB6bke"
|
15
|
+
- Rob Sanheim
|
16
|
+
- Muness Alrubaie
|
17
|
+
- Relevance
|
18
|
+
autorequire:
|
19
|
+
bindir: bin
|
20
|
+
cert_chain: []
|
21
|
+
|
22
|
+
date: 2012-11-12 00:00:00 Z
|
23
|
+
dependencies:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
version_requirements: *id001
|
35
|
+
prerelease: false
|
36
|
+
type: :runtime
|
37
|
+
name: activesupport
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 7
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
version: 3.0.0
|
50
|
+
version_requirements: *id002
|
51
|
+
prerelease: false
|
52
|
+
type: :runtime
|
53
|
+
name: actionmailer
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
version_requirements: *id003
|
65
|
+
prerelease: false
|
66
|
+
type: :development
|
67
|
+
name: rake
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
version_requirements: *id004
|
79
|
+
prerelease: false
|
80
|
+
type: :development
|
81
|
+
name: rdoc
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
version_requirements: *id005
|
93
|
+
prerelease: false
|
94
|
+
type: :development
|
95
|
+
name: rspec
|
96
|
+
description: Super simple capistrano deployment notifications. Forked from relevance/cap_gun.
|
97
|
+
email:
|
98
|
+
- sebastian.roebke@xing.com
|
99
|
+
executables: []
|
100
|
+
|
101
|
+
extensions: []
|
102
|
+
|
103
|
+
extra_rdoc_files: []
|
104
|
+
|
105
|
+
files:
|
106
|
+
- .gitignore
|
107
|
+
- CHANGELOG
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE
|
110
|
+
- README.markdown
|
111
|
+
- Rakefile
|
112
|
+
- cap_gun.gemspec
|
113
|
+
- lib/cap_gun.rb
|
114
|
+
- lib/cap_gun/presenter.rb
|
115
|
+
- spec/cap_gun_spec.rb
|
116
|
+
- spec/presenter_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
homepage: https://github.com/xing/cap_gun
|
119
|
+
licenses: []
|
120
|
+
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
hash: 3
|
132
|
+
segments:
|
133
|
+
- 0
|
134
|
+
version: "0"
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ">"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
hash: 25
|
141
|
+
segments:
|
142
|
+
- 1
|
143
|
+
- 3
|
144
|
+
- 1
|
145
|
+
version: 1.3.1
|
146
|
+
requirements: []
|
147
|
+
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.8.24
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: Super simple capistrano deployment notifications. Forked from relevance/cap_gun.
|
153
|
+
test_files: []
|
154
|
+
|