cerberus 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +8 -0
- data/README +11 -1
- data/Rakefile +2 -3
- data/lib/cerberus/builder/ruby_base.rb +1 -1
- data/lib/cerberus/cli.rb +1 -2
- data/lib/cerberus/config.example.yml +8 -5
- data/lib/cerberus/config.rb +0 -1
- data/lib/cerberus/constants.rb +3 -3
- data/lib/cerberus/manager.rb +13 -8
- data/lib/cerberus/publisher/base.rb +8 -4
- data/lib/cerberus/publisher/campfire.rb +124 -0
- data/lib/cerberus/scm/darcs.rb +31 -16
- data/lib/cerberus/scm/svn.rb +17 -7
- data/lib/cerberus/utils.rb +9 -0
- data/test/data/darcs.zip +0 -0
- data/test/data/{application.dump → subversion.dump} +0 -0
- data/test/functional_test.rb +78 -1
- data/test/integration_test.rb +14 -2
- data/test/mock/marshmallow.rb +15 -0
- data/test/rss_publisher_test.rb +1 -1
- data/test/test_helper.rb +28 -3
- metadata +7 -14
- data/lib/cerberus/version.rb +0 -5
data/CHANGES
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
= Cerberus Changelog
|
2
2
|
|
3
|
+
== Version 0.3.0
|
4
|
+
Fix release
|
5
|
+
|
6
|
+
* Added support of Campfire publisher
|
7
|
+
* Added changeset_url option that adds quick link to browsable chanelist view
|
8
|
+
* Added possibility to specify user_name and password for Subversion commands
|
9
|
+
* Added support of Darcs VCS
|
10
|
+
|
3
11
|
== Version 0.2.4
|
4
12
|
Features release
|
5
13
|
|
data/README
CHANGED
@@ -62,4 +62,14 @@ cerberus buildall #Run all available projects
|
|
62
62
|
|
63
63
|
It will check out latest sources and run tests for your application. If tests are broken - recipients will receive notifications.
|
64
64
|
|
65
|
-
But of course better run Cerberus automatically from Cron. Run Cerberus for project each 10 minutes would be ok.
|
65
|
+
But of course better run Cerberus automatically from Cron. Run Cerberus for project each 10 minutes would be ok.
|
66
|
+
|
67
|
+
== License
|
68
|
+
|
69
|
+
This plugin is licensed under the MIT license. Complete license text
|
70
|
+
is included in the LICENSE file.
|
71
|
+
|
72
|
+
== Author
|
73
|
+
|
74
|
+
This software was created by Anatol Pomozov <anatol.pomozov@gmail.com> and is
|
75
|
+
located at http://cerberus.rubyforge.org.
|
data/Rakefile
CHANGED
@@ -4,11 +4,11 @@ require 'rake/testtask'
|
|
4
4
|
require 'rake/packagetask'
|
5
5
|
require 'rake/gempackagetask'
|
6
6
|
|
7
|
-
require "./lib/cerberus/
|
7
|
+
require "./lib/cerberus/constants"
|
8
8
|
|
9
9
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
10
|
PKG_NAME = 'cerberus'
|
11
|
-
PKG_VERSION = Cerberus::VERSION
|
11
|
+
PKG_VERSION = Cerberus::VERSION + PKG_BUILD
|
12
12
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
13
13
|
|
14
14
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
@@ -50,7 +50,6 @@ GEM_SPEC = Gem::Specification.new do |s|
|
|
50
50
|
Cerberus could be easily invoked from Cron (for Unix) or nnCron (for Windows) utilities.
|
51
51
|
DESC
|
52
52
|
|
53
|
-
s.add_dependency 'actionmailer', '>= 1.2.5'
|
54
53
|
s.add_dependency 'rake', '>= 0.7.1'
|
55
54
|
s.add_dependency 'jabber4r', '>= 0.8.0'
|
56
55
|
s.add_dependency 'Ruby-IRC', '>= 1.0.3'
|
@@ -28,7 +28,7 @@ class Cerberus::Builder::RubyBase
|
|
28
28
|
silence_stream(STDERR) {
|
29
29
|
ext.each do |e|
|
30
30
|
begin
|
31
|
-
out = `#{@config[:bin_path]}#{@cmd}#{e} --version`
|
31
|
+
out = `#{@config[:bin_path]}#{@cmd}#{e} --version 2>&1`
|
32
32
|
return "#{@cmd}#{e}" if out =~ /#{@cmd}/
|
33
33
|
rescue
|
34
34
|
end
|
data/lib/cerberus/cli.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'cerberus/manager'
|
2
2
|
require 'cerberus/utils'
|
3
|
-
require 'cerberus/version'
|
4
3
|
require 'cerberus/constants'
|
5
4
|
|
6
5
|
module Cerberus
|
@@ -62,6 +61,6 @@ module Cerberus
|
|
62
61
|
cerberus build <APPLICATION_NAME> --- build watched application
|
63
62
|
cerberus buildall --- build all watched applications
|
64
63
|
|
65
|
-
Version #{Cerberus::VERSION
|
64
|
+
Version #{Cerberus::VERSION}
|
66
65
|
}.gsub("\n ","\n")
|
67
66
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
#Copy this file to config.yml and configure notification services
|
2
2
|
publisher:
|
3
|
-
active: mail jabber rss
|
3
|
+
active: mail jabber rss campfire
|
4
4
|
mail:
|
5
5
|
address: smtp.gmail.com
|
6
6
|
port: 587
|
7
7
|
domain: gmail.com
|
8
8
|
authentication: plain
|
9
9
|
user_name: someuser
|
10
|
-
password:
|
10
|
+
password: somepassword
|
11
11
|
jabber:
|
12
12
|
jid: cerberus@gtalk.google.com
|
13
13
|
port: 5222
|
@@ -17,8 +17,11 @@ publisher:
|
|
17
17
|
nick: cerb
|
18
18
|
server: irc.freenode.net
|
19
19
|
channel: cerberus
|
20
|
-
|
21
|
-
|
20
|
+
# campfire:
|
21
|
+
# url: http://someemail:password@cerberustool.campfirenow.com/room/51660
|
22
|
+
# rss:
|
23
|
+
# file: /usr/www/rss.xml
|
22
24
|
builder:
|
23
25
|
rake:
|
24
|
-
task: migrate test
|
26
|
+
task: migrate test
|
27
|
+
#changeset_url: POINT_TO_YOUR_TRAC/changeset/
|
data/lib/cerberus/config.rb
CHANGED
data/lib/cerberus/constants.rb
CHANGED
data/lib/cerberus/manager.rb
CHANGED
@@ -10,18 +10,23 @@ require 'cerberus/publisher/mail'
|
|
10
10
|
require 'cerberus/publisher/jabber'
|
11
11
|
require 'cerberus/publisher/irc'
|
12
12
|
require 'cerberus/publisher/rss'
|
13
|
+
require 'cerberus/publisher/campfire'
|
14
|
+
|
13
15
|
require 'cerberus/scm/svn'
|
16
|
+
require 'cerberus/scm/darcs'
|
14
17
|
|
15
18
|
module Cerberus
|
16
19
|
SCM_TYPES = {
|
17
|
-
:svn => Cerberus::SCM::SVN
|
20
|
+
:svn => Cerberus::SCM::SVN,
|
21
|
+
:darcs => Cerberus::SCM::Darcs
|
18
22
|
}
|
19
23
|
|
20
24
|
PUBLISHER_TYPES = {
|
21
25
|
:mail => Cerberus::Publisher::Mail,
|
22
26
|
:jabber => Cerberus::Publisher::Jabber,
|
23
27
|
:irc => Cerberus::Publisher::IRC,
|
24
|
-
:rss => Cerberus::Publisher::RSS
|
28
|
+
:rss => Cerberus::Publisher::RSS,
|
29
|
+
:campfire => Cerberus::Publisher::Campfire
|
25
30
|
}
|
26
31
|
|
27
32
|
BUILDER_TYPES = {
|
@@ -41,7 +46,7 @@ module Cerberus
|
|
41
46
|
def run
|
42
47
|
scm_type = @cli_options[:scm] || 'svn'
|
43
48
|
say "SCM #{scm_type} not supported" unless SCM_TYPES[scm_type.to_sym]
|
44
|
-
scm = SCM_TYPES[scm_type.to_sym].new(@path, @cli_options)
|
49
|
+
scm = SCM_TYPES[scm_type.to_sym].new(@path, Config.new(nil, @cli_options))
|
45
50
|
say "Can't find any #{scm_type} application under #{@path}" unless scm.url
|
46
51
|
|
47
52
|
application_name = @cli_options[:application_name] || extract_project_name(@path)
|
@@ -54,11 +59,11 @@ module Cerberus
|
|
54
59
|
app_config = { 'scm' => {
|
55
60
|
'url' => scm.url,
|
56
61
|
'type' => scm_type },
|
57
|
-
'publisher' => {'mail' => {'recipients' => @cli_options[:recipients]}}
|
58
|
-
'builder' => {'type' => @cli_options[:builder]}
|
62
|
+
'publisher' => {'mail' => {'recipients' => @cli_options[:recipients]}}
|
59
63
|
}
|
64
|
+
app_config['builder'] = {'type' => @cli_options[:builder]} if @cli_options[:builder]
|
60
65
|
dump_yml(config_name, app_config)
|
61
|
-
puts "Application '#{application_name}'
|
66
|
+
puts "Application '#{application_name}' has been added to Cerberus successfully" unless @cli_options[:quiet]
|
62
67
|
end
|
63
68
|
|
64
69
|
private
|
@@ -153,8 +158,8 @@ module Cerberus
|
|
153
158
|
if ENV['CERBERUS_ENV'] == 'TEST'
|
154
159
|
raise e
|
155
160
|
else
|
156
|
-
File.open("#{HOME}/
|
157
|
-
f.puts Time.now.strftime("%a, %d %b %Y %H:%M:%S
|
161
|
+
File.open("#{HOME}/error.log", File::WRONLY|File::APPEND|File::CREAT) do |f|
|
162
|
+
f.puts Time.now.strftime("%a, %d %b %Y %H:%M:%S [#{@config[:application_name]}] -- #{e.class}")
|
158
163
|
f.puts e.message unless e.message.blank?
|
159
164
|
f.puts e.backtrace.collect{|line| ' '*5 + line}
|
160
165
|
f.puts "\n"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'cerberus/
|
1
|
+
require 'cerberus/constants'
|
2
2
|
|
3
3
|
module Cerberus
|
4
4
|
module Publisher
|
@@ -19,10 +19,14 @@ module Cerberus
|
|
19
19
|
end
|
20
20
|
|
21
21
|
subject = "[#{options[:application_name]}] #{subject}"
|
22
|
-
generated_by = "--\nCerberus #{Cerberus::VERSION
|
23
|
-
body = [ manager.scm.last_commit_message
|
22
|
+
generated_by = "--\nCerberus #{Cerberus::VERSION}, http://cerberus.rubyforge.org/"
|
23
|
+
body = [ manager.scm.last_commit_message ]
|
24
|
+
if options[:changeset_url]
|
25
|
+
body << options[:changeset_url] + manager.scm.current_revision.to_s + "\n"
|
26
|
+
end
|
27
|
+
body += [ manager.builder.output, generated_by ]
|
24
28
|
|
25
|
-
return subject, body
|
29
|
+
return subject, body.join("\n")
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'cerberus/publisher/base'
|
2
|
+
|
3
|
+
class Cerberus::Publisher::Campfire < Cerberus::Publisher::Base
|
4
|
+
def self.publish(state, manager, options)
|
5
|
+
url = options[:publisher, :campfire, :url]
|
6
|
+
|
7
|
+
subject,body = Cerberus::Publisher::Base.formatted_message(state, manager, options)
|
8
|
+
Marshmallow.say(url, subject)
|
9
|
+
Marshmallow.paste(url, body)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
#I've changed standard url from /rooms/ to /room/ as better choise
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
# Marshmallow, the campfire chatbot
|
17
|
+
#
|
18
|
+
# You need to know one the following:
|
19
|
+
# (a) the secret public URL, or
|
20
|
+
# (b) an account/password for your room and the room number.
|
21
|
+
#
|
22
|
+
# Usage:
|
23
|
+
# to login with a password:
|
24
|
+
#
|
25
|
+
# bot = Marshmallow.new( :domain => 'mydomain', :ssl => true )
|
26
|
+
# bot.login :method => :login,
|
27
|
+
# :username => "yourbot@email.com",
|
28
|
+
# :password => "passw0rd",
|
29
|
+
# :room => "11234"
|
30
|
+
# bot.say("So many ponies in here! I want one!")
|
31
|
+
#
|
32
|
+
# to use the public url:
|
33
|
+
#
|
34
|
+
# Marshmallow.domain = 'mydomain'
|
35
|
+
# bot = Marshmallow.new
|
36
|
+
# bot.login( :url => 'aDxf3' )
|
37
|
+
# bot.say "Ponies!!"
|
38
|
+
# bot.paste "<script type='text/javascript'>\nalert('Ponies!')\n</script>"
|
39
|
+
#
|
40
|
+
|
41
|
+
class Marshmallow
|
42
|
+
require 'net/https'
|
43
|
+
require 'open-uri'
|
44
|
+
require 'cgi'
|
45
|
+
require 'yaml'
|
46
|
+
|
47
|
+
def self.version
|
48
|
+
"0.2.5"
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :domain
|
52
|
+
|
53
|
+
def self.say(to, what)
|
54
|
+
connect(to) { |bot| bot.say(what) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.paste(to, what)
|
58
|
+
connect(to) { |bot| bot.paste(what) }
|
59
|
+
end
|
60
|
+
|
61
|
+
# https://david:stuff@37s.campfirenow.com/room/11234
|
62
|
+
def self.connect(to)
|
63
|
+
if to =~ %r{(http|https)://([^:]+):(.+)@([^.]+).campfirenow.com/room/(\d+)}
|
64
|
+
protocol, username, password, domain, room = $1, $2, $3, $4, $5
|
65
|
+
else
|
66
|
+
raise "#{to} didn't match format, try something like https://david:stuff@37s.campfirenow.com/room/11234"
|
67
|
+
end
|
68
|
+
|
69
|
+
bot = new(:domain => domain, :ssl => (protocol == "https"))
|
70
|
+
bot.login(:username => username, :password => password, :method => :login, :room => room)
|
71
|
+
|
72
|
+
yield bot
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(options={})
|
76
|
+
@debug = options[:debug]
|
77
|
+
@domain = options[:domain] || @@domain
|
78
|
+
@ssl = options[:ssl]
|
79
|
+
end
|
80
|
+
|
81
|
+
def login(options)
|
82
|
+
options = { :method => :url, :username => 'Marshmallow' }.merge(options)
|
83
|
+
|
84
|
+
@req = Net::HTTP::new("#{@domain}.campfirenow.com", @ssl ? 443 : 80)
|
85
|
+
@req.use_ssl = @ssl
|
86
|
+
@req.verify_mode = OpenSSL::SSL::VERIFY_NONE if @ssl
|
87
|
+
headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
88
|
+
|
89
|
+
case options[:method]
|
90
|
+
when :url
|
91
|
+
res = @req.post("/#{options[:url]}", "name=#{options[:username]}", headers)
|
92
|
+
# parse our response headers for the room number.. magic!
|
93
|
+
@room_id = res['location'].scan(/room\/(\d+)/).to_s
|
94
|
+
puts res.body if @debug
|
95
|
+
|
96
|
+
when :login
|
97
|
+
params = "email_address=#{CGI.escape(options[:username])}&password=#{CGI.escape(options[:password])}"
|
98
|
+
puts params if @debug
|
99
|
+
res = @req.post("/login/", params, headers)
|
100
|
+
@room_id = options[:room]
|
101
|
+
puts "Logging into room #{@room_id}" if @debug
|
102
|
+
puts res.body if @debug
|
103
|
+
end
|
104
|
+
|
105
|
+
@headers = { 'Cookie' => res.response['set-cookie'] }
|
106
|
+
res2 = @req.get(res['location'], @headers)
|
107
|
+
puts res2.body if @debug
|
108
|
+
|
109
|
+
# refresh our headers
|
110
|
+
@headers = { 'Cookie' => res.response['set-cookie'] }
|
111
|
+
@req.get("/room/#{@room_id}/") # join the room if necessary
|
112
|
+
return @headers
|
113
|
+
end
|
114
|
+
|
115
|
+
def paste(message)
|
116
|
+
say(message, true)
|
117
|
+
end
|
118
|
+
|
119
|
+
def say(message, paste=false)
|
120
|
+
puts "Posting #{message}" if @debug
|
121
|
+
res = @req.post("/room/#{@room_id}/speak", "#{'paste=true&' if paste}message=#{CGI.escape(message.to_s)}", @headers)
|
122
|
+
puts res.body if @debug
|
123
|
+
end
|
124
|
+
end
|
data/lib/cerberus/scm/darcs.rb
CHANGED
@@ -8,41 +8,56 @@ class Cerberus::SCM::Darcs
|
|
8
8
|
|
9
9
|
def update!
|
10
10
|
if test(?d, @path + '/_darcs')
|
11
|
-
@status = execute(
|
11
|
+
@status = execute('pull', '-v -a')
|
12
12
|
else
|
13
|
-
FileUtils.
|
14
|
-
@
|
13
|
+
FileUtils.rm_rf(@path) if test(?d,@path)
|
14
|
+
FileUtils.mkpath(File.basename(@path)) unless test(?d,File.basename(@path))
|
15
|
+
|
16
|
+
encoded_url = (@config[:scm, :url].include?(' ') ? "\"#{@config[:scm, :url]}\"" : @config[:scm, :url])
|
17
|
+
@status = execute("get", "--partial #{encoded_url}")
|
15
18
|
end
|
19
|
+
|
20
|
+
extract_last_commit_info
|
16
21
|
end
|
17
22
|
|
18
23
|
def has_changes?
|
19
|
-
@status =~ /
|
24
|
+
return false if @status =~ /No remote changes to pull in!/
|
25
|
+
return true if @status =~ /We have the following new \(to them\) patches:/
|
26
|
+
return true if @status =~ /Copying patch \d+ of \d+\.\.\. done!/
|
27
|
+
return false
|
20
28
|
end
|
21
29
|
|
22
30
|
def current_revision
|
23
|
-
|
31
|
+
@date
|
24
32
|
end
|
25
33
|
|
26
34
|
def url
|
27
|
-
|
35
|
+
@path
|
28
36
|
end
|
29
37
|
|
30
38
|
def last_commit_message
|
31
|
-
message
|
32
|
-
#strip first line that contains command line itself (svn log --limit ...)
|
33
|
-
if ((idx = message.index('-'*72)) != 0 )
|
34
|
-
message[idx..-1]
|
35
|
-
else
|
36
|
-
message
|
37
|
-
end
|
39
|
+
@message
|
38
40
|
end
|
39
41
|
|
40
42
|
def last_author
|
41
|
-
|
43
|
+
@author
|
42
44
|
end
|
43
45
|
|
46
|
+
def output
|
47
|
+
@status
|
48
|
+
end
|
44
49
|
private
|
45
|
-
def execute(command, parameters = nil,
|
46
|
-
|
50
|
+
def execute(command, parameters = nil, with_path = true)
|
51
|
+
cmd = "#{@config[:bin_path]}darcs #{command} #{parameters} --repodir=#{@encoded_path}"
|
52
|
+
`#{cmd}`
|
53
|
+
end
|
54
|
+
|
55
|
+
def extract_last_commit_info
|
56
|
+
xml_message = execute('changes', "--last 1 --xml-output")
|
57
|
+
require 'rexml/document'
|
58
|
+
xml = REXML::Document.new(xml_message)
|
59
|
+
@author = xml.elements["changelog/patch/@author"].value
|
60
|
+
@date = xml.elements["changelog/patch/@date"].value
|
61
|
+
@message = xml.elements["changelog/patch/name"].get_text.value
|
47
62
|
end
|
48
63
|
end
|
data/lib/cerberus/scm/svn.rb
CHANGED
@@ -25,7 +25,7 @@ class Cerberus::SCM::SVN
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def has_changes?
|
28
|
-
@status =~ /[A-Z]\s+[\w\/]+/
|
28
|
+
@status =~ /[A-Z]\s+[\w\/]+/ ? true : false
|
29
29
|
end
|
30
30
|
|
31
31
|
def current_revision
|
@@ -39,7 +39,7 @@ class Cerberus::SCM::SVN
|
|
39
39
|
def last_commit_message
|
40
40
|
message = execute("log", "--limit 1 -v")
|
41
41
|
#strip first line that contains command line itself (svn log --limit ...)
|
42
|
-
if (
|
42
|
+
if (idx = message.index('-'*72))
|
43
43
|
message[idx..-1]
|
44
44
|
else
|
45
45
|
message
|
@@ -56,16 +56,26 @@ class Cerberus::SCM::SVN
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def info
|
59
|
-
|
60
|
-
|
59
|
+
unless @info
|
60
|
+
output = execute("info")
|
61
|
+
@info = YAML.load(output)
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
unless @info.is_a?(Hash) or @info['Repository Root'] #.size > 8
|
64
|
+
say "Could not parse svn output. Seems source directory #{@encoded_path} is corrupted.\n#{output}"
|
65
|
+
end
|
64
66
|
end
|
65
67
|
@info
|
66
68
|
end
|
67
69
|
|
68
70
|
def execute(command, parameters = nil, pre_parameters = nil)
|
69
|
-
`#{@config[:bin_path]}svn #{command} #{pre_parameters} #{@encoded_path} #{parameters}`
|
71
|
+
`#{@config[:bin_path]}svn #{command} #{auth_options()} #{pre_parameters} #{@encoded_path} #{parameters}`
|
72
|
+
end
|
73
|
+
|
74
|
+
def auth_options
|
75
|
+
auth = []
|
76
|
+
auth << "--username #{@config[:scm, :user_name]}" if @config[:scm, :user_name]
|
77
|
+
auth << "--password #{@config[:scm, :password]}" if @config[:scm, :password]
|
78
|
+
|
79
|
+
auth.join(' ')
|
70
80
|
end
|
71
81
|
end
|
data/lib/cerberus/utils.rb
CHANGED
@@ -26,6 +26,15 @@ module Cerberus
|
|
26
26
|
def load_yml(file_name, default = {})
|
27
27
|
File.exists?(file_name) ? YAML::load(IO.read(file_name)) : default
|
28
28
|
end
|
29
|
+
|
30
|
+
def silence_stream(stream)
|
31
|
+
old_stream = stream.dup
|
32
|
+
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
|
33
|
+
stream.sync = true
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
stream.reopen(old_stream)
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
data/test/data/darcs.zip
ADDED
Binary file
|
File without changes
|
data/test/functional_test.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
require 'cerberus/cli'
|
4
|
+
require 'mock/marshmallow'
|
4
5
|
|
5
6
|
class FunctionalTest < Test::Unit::TestCase
|
6
7
|
def setup
|
@@ -46,7 +47,7 @@ class FunctionalTest < Test::Unit::TestCase
|
|
46
47
|
def test_build
|
47
48
|
add_application('myapp', SVN_URL)
|
48
49
|
|
49
|
-
build = Cerberus::BuildCommand.new('myapp')
|
50
|
+
build = Cerberus::BuildCommand.new('myapp', :changeset_url => 'http://someurl.changeset.com/')
|
50
51
|
build.run
|
51
52
|
assert_equal 1, ActionMailer::Base.deliveries.size #first email that project was setup
|
52
53
|
mail = ActionMailer::Base.deliveries[0]
|
@@ -56,6 +57,7 @@ class FunctionalTest < Test::Unit::TestCase
|
|
56
57
|
assert_match /1 tests, 1 assertions, 0 failures, 0 errors/, output
|
57
58
|
assert output !~ /Task 'custom1' has been invoked/
|
58
59
|
assert_equal '[myapp] Cerberus set up for project (#2)', mail.subject
|
60
|
+
assert output =~ %r{http://someurl.changeset.com/2}
|
59
61
|
|
60
62
|
status_file = HOME + '/work/myapp/status.log'
|
61
63
|
assert File.exists?(status_file)
|
@@ -166,4 +168,79 @@ class FunctionalTest < Test::Unit::TestCase
|
|
166
168
|
|
167
169
|
assert !File.exists?(HOME + "/work/rake_cust/logs")
|
168
170
|
end
|
171
|
+
|
172
|
+
def test_darcs
|
173
|
+
add_application('darcsapp', DARCS_URL, :scm => {:type => 'darcs'})
|
174
|
+
|
175
|
+
build = Cerberus::BuildCommand.new('darcsapp')
|
176
|
+
build.run
|
177
|
+
assert build.scm.has_changes?
|
178
|
+
assert_equal 1, ActionMailer::Base.deliveries.size #first email that project was setup
|
179
|
+
mail = ActionMailer::Base.deliveries[0]
|
180
|
+
output = mail.body
|
181
|
+
|
182
|
+
#Check outpus that run needed tasks
|
183
|
+
assert_match /1 tests, 1 assertions, 0 failures, 0 errors/, output
|
184
|
+
assert output !~ /Task 'custom1' has been invoked/
|
185
|
+
assert_equal '[darcsapp] Cerberus set up for project (#20061010090920)', mail.subject
|
186
|
+
|
187
|
+
status_file = HOME + '/work/darcsapp/status.log'
|
188
|
+
assert File.exists?(status_file)
|
189
|
+
assert_equal 'succesful', IO.read(status_file)
|
190
|
+
assert 1, Dir[HOME + "/work/darcsapp/logs/*.log"].size
|
191
|
+
|
192
|
+
#There were no changes - no reaction should be
|
193
|
+
build = Cerberus::BuildCommand.new('darcsapp')
|
194
|
+
build.run
|
195
|
+
assert_equal false, build.scm.has_changes?
|
196
|
+
assert_equal 1, ActionMailer::Base.deliveries.size #first email that project was setup
|
197
|
+
assert 1, Dir[HOME + "/work/darcsapp/logs/*.log"].size
|
198
|
+
|
199
|
+
#now we add new broken test
|
200
|
+
test_case_name = "test/#{rand(10000)}_test.rb"
|
201
|
+
File.open(DARCS_REPO + '/' + test_case_name, 'w') { |f|
|
202
|
+
f << "require 'test/unit'
|
203
|
+
class A#{rand(10000)}Test < Test::Unit::TestCase
|
204
|
+
def test_ok
|
205
|
+
assert false
|
206
|
+
end
|
207
|
+
end"
|
208
|
+
}
|
209
|
+
|
210
|
+
curr_dir = Dir.pwd
|
211
|
+
Dir.chdir DARCS_REPO
|
212
|
+
`darcs add #{test_case_name}`
|
213
|
+
`darcs record -a -A test@gmail.com -m somepatch`
|
214
|
+
Dir.chdir curr_dir
|
215
|
+
|
216
|
+
build = Cerberus::BuildCommand.new('darcsapp')
|
217
|
+
build.run
|
218
|
+
assert build.scm.has_changes?
|
219
|
+
assert_equal 2, ActionMailer::Base.deliveries.size #first email that project was setup
|
220
|
+
assert 2, Dir[HOME + "/work/darcsapp/logs/*.log"].size
|
221
|
+
|
222
|
+
build = Cerberus::BuildCommand.new('darcsapp')
|
223
|
+
build.run
|
224
|
+
assert_equal false, build.scm.has_changes?
|
225
|
+
assert_equal 2, ActionMailer::Base.deliveries.size #first email that project was setup
|
226
|
+
assert 2, Dir[HOME + "/work/darcsapp/logs/*.log"].size
|
227
|
+
|
228
|
+
#Now we broke remote repository (imiitate that network unaccessage)
|
229
|
+
FileUtils.rm_rf DARCS_REPO
|
230
|
+
build = Cerberus::BuildCommand.new('darcsapp')
|
231
|
+
build.run
|
232
|
+
assert_equal false, build.scm.has_changes?
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_campfire_publisher
|
236
|
+
#there were no any messages cause login/password is incorrect. We just check that there was no any exceptions
|
237
|
+
add_application('campapp', SVN_URL, 'publisher' => {'active' => 'campfire', 'campfire' =>
|
238
|
+
{'url' => 'http://mail@gmail.com:somepwd@cerberustool.campfirenow.com/room/5166022'}
|
239
|
+
})
|
240
|
+
|
241
|
+
build = Cerberus::BuildCommand.new('campapp')
|
242
|
+
build.run
|
243
|
+
|
244
|
+
assert_equal 2, Marshmallow.counter
|
245
|
+
end
|
169
246
|
end
|
data/test/integration_test.rb
CHANGED
@@ -13,7 +13,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def test_add_project_as_url
|
15
15
|
output = run_cerb(" add #{SVN_URL} ")
|
16
|
-
assert_match /
|
16
|
+
assert_match /has been added to Cerberus successfully/, output
|
17
17
|
assert File.exists?(HOME + '/config/svn_repo.yml')
|
18
18
|
assert_equal SVN_URL, load_yml(HOME + '/config/svn_repo.yml')['scm']['url']
|
19
19
|
|
@@ -26,11 +26,12 @@ class IntegrationTest < Test::Unit::TestCase
|
|
26
26
|
|
27
27
|
def test_add_project_with_parameters
|
28
28
|
output = run_cerb(" add #{SVN_URL} APPLICATION_NAME=hello_world RECIPIENTS=aa@gmail.com BUILDER=maven2")
|
29
|
-
assert_match /
|
29
|
+
assert_match /has been added to Cerberus successfully/, output
|
30
30
|
|
31
31
|
assert File.exists?(HOME + '/config/hello_world.yml')
|
32
32
|
cfg = load_yml(HOME + '/config/hello_world.yml')
|
33
33
|
|
34
|
+
assert_equal 'svn', cfg['scm']['type']
|
34
35
|
assert_equal SVN_URL, cfg['scm']['url']
|
35
36
|
assert_equal 'aa@gmail.com', cfg['publisher']['mail']['recipients']
|
36
37
|
assert_equal 'maven2', cfg['builder']['type']
|
@@ -44,6 +45,17 @@ class IntegrationTest < Test::Unit::TestCase
|
|
44
45
|
assert_equal 'succesful', IO.read(HOME + '/work/svn_repo/status.log')
|
45
46
|
end
|
46
47
|
|
48
|
+
def test_add_darcs_scm
|
49
|
+
output = run_cerb(" add #{DARCS_URL} SCM=darcs")
|
50
|
+
assert_match /has been added to Cerberus successfully/, output
|
51
|
+
|
52
|
+
assert File.exists?(HOME + '/config/darcs_repo.yml')
|
53
|
+
cfg = load_yml(HOME + '/config/darcs_repo.yml')
|
54
|
+
|
55
|
+
assert_equal 'darcs', cfg['scm']['type']
|
56
|
+
assert_equal DARCS_URL, cfg['scm']['url']
|
57
|
+
end
|
58
|
+
|
47
59
|
def test_run_unexist_project
|
48
60
|
output = run_cerb("build some_project")
|
49
61
|
assert_equal 'Project some_project does not present in Cerberus', output.strip
|
data/test/rss_publisher_test.rb
CHANGED
@@ -15,7 +15,7 @@ class RSSPublisherTest < Test::Unit::TestCase
|
|
15
15
|
xml = REXML::Document.new(IO.read(rss_file.path))
|
16
16
|
|
17
17
|
assert_equal '[RSS<App] Cerberus set up for project (#1235)', xml.elements["rss/channel/item/title/"].get_text.value
|
18
|
-
assert_match %r{<pre>last message\
|
18
|
+
assert_match %r{<pre>last message\nthis is output\n--\nCerberus 0.\d.\d, http://cerberus.rubyforge.org/</pre>},
|
19
19
|
xml.elements["rss/channel/item/description/"].get_text.value
|
20
20
|
end
|
21
21
|
end
|
data/test/test_helper.rb
CHANGED
@@ -14,18 +14,31 @@ class Test::Unit::TestCase
|
|
14
14
|
SVN_REPO = TEMP_DIR + '/svn_repo'
|
15
15
|
SVN_URL = 'file:///' + SVN_REPO.gsub(/\\/,'/').gsub(/^\//,'').gsub(' ', '%20')
|
16
16
|
|
17
|
+
DARCS_REPO = TEMP_DIR + '/darcs_repo'
|
18
|
+
DARCS_URL = 'file:///' + DARCS_REPO.gsub(/\\/,'/').gsub(/^\//,'').gsub(' ', '%20')
|
19
|
+
|
17
20
|
HOME = TEMP_DIR + '/home'
|
18
21
|
ENV['CERBERUS_HOME'] = HOME
|
19
22
|
ENV['CERBERUS_ENV'] = 'TEST'
|
20
23
|
|
21
|
-
def self.
|
24
|
+
def self.refresh_repos
|
22
25
|
FileUtils.rm_rf TEMP_DIR
|
23
26
|
FileUtils.mkpath SVN_REPO
|
24
27
|
`svnadmin create "#{SVN_REPO}"`
|
25
|
-
`svnadmin load "#{SVN_REPO}" < "#{File.dirname(__FILE__)}/data/
|
28
|
+
`svnadmin load "#{SVN_REPO}" < "#{File.dirname(__FILE__)}/data/subversion.dump"`
|
29
|
+
|
30
|
+
require 'zip/zip'
|
31
|
+
FileUtils.mkpath DARCS_REPO
|
32
|
+
Zip::ZipFile::open("#{File.dirname(__FILE__)}/data/darcs.zip") {|zf|
|
33
|
+
zf.each { |e|
|
34
|
+
fpath = File.join(DARCS_REPO, e.name)
|
35
|
+
FileUtils.mkdir_p(File.dirname(fpath))
|
36
|
+
zf.extract(e, fpath)
|
37
|
+
}
|
38
|
+
}
|
26
39
|
end
|
27
40
|
|
28
|
-
|
41
|
+
refresh_repos
|
29
42
|
|
30
43
|
CERBERUS_PATH = File.expand_path(File.dirname(__FILE__) + '/../')
|
31
44
|
def run_cerb(args)
|
@@ -63,6 +76,18 @@ end"
|
|
63
76
|
def add_config(options)
|
64
77
|
dump_yml(HOME + "/config.yml", options)
|
65
78
|
end
|
79
|
+
|
80
|
+
# Overrides the method +method_name+ in +obj+ with the passed block
|
81
|
+
def override_method(obj, method_name, &block)
|
82
|
+
# Get the singleton class/eigenclass for 'obj'
|
83
|
+
klass = class <<obj; self; end
|
84
|
+
|
85
|
+
# Undefine the old method (using 'send' since 'undef_method' is protected)
|
86
|
+
klass.send(:undef_method, method_name)
|
87
|
+
|
88
|
+
# Create the new method
|
89
|
+
klass.send(:define_method, method_name, block)
|
90
|
+
end
|
66
91
|
end
|
67
92
|
|
68
93
|
require 'cerberus/config'
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.0.
|
2
|
+
rubygems_version: 0.9.0.6
|
3
3
|
specification_version: 1
|
4
4
|
name: cerberus
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.3.0
|
7
|
+
date: 2006-10-23 00:00:00 +04:00
|
8
8
|
summary: Cerberus is a Continuous Integration tool that could be easily run from Cron.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -43,13 +43,13 @@ files:
|
|
43
43
|
- lib/cerberus/publisher
|
44
44
|
- lib/cerberus/scm
|
45
45
|
- lib/cerberus/utils.rb
|
46
|
-
- lib/cerberus/version.rb
|
47
46
|
- lib/cerberus/builder/maven2.rb
|
48
47
|
- lib/cerberus/builder/rake.rb
|
49
48
|
- lib/cerberus/builder/rant.rb
|
50
49
|
- lib/cerberus/builder/ruby_base.rb
|
51
50
|
- lib/cerberus/helper/xchar.rb
|
52
51
|
- lib/cerberus/publisher/base.rb
|
52
|
+
- lib/cerberus/publisher/campfire.rb
|
53
53
|
- lib/cerberus/publisher/irc.rb
|
54
54
|
- lib/cerberus/publisher/jabber.rb
|
55
55
|
- lib/cerberus/publisher/mail.rb
|
@@ -69,10 +69,12 @@ files:
|
|
69
69
|
- test/mock
|
70
70
|
- test/rss_publisher_test.rb
|
71
71
|
- test/test_helper.rb
|
72
|
-
- test/data/
|
72
|
+
- test/data/darcs.zip
|
73
|
+
- test/data/subversion.dump
|
73
74
|
- test/mock/irc.rb
|
74
75
|
- test/mock/jabber4r.rb
|
75
76
|
- test/mock/manager.rb
|
77
|
+
- test/mock/marshmallow.rb
|
76
78
|
- LICENSE
|
77
79
|
- README
|
78
80
|
- CHANGES
|
@@ -92,15 +94,6 @@ extensions: []
|
|
92
94
|
requirements: []
|
93
95
|
|
94
96
|
dependencies:
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: actionmailer
|
97
|
-
version_requirement:
|
98
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
99
|
-
requirements:
|
100
|
-
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 1.2.5
|
103
|
-
version:
|
104
97
|
- !ruby/object:Gem::Dependency
|
105
98
|
name: rake
|
106
99
|
version_requirement:
|