lib/autobuild/reporting.rb in autobuild-0.4 vs lib/autobuild/reporting.rb in autobuild-0.5

- old
+ new

@@ -1,78 +1,114 @@ require 'rmail' require 'rmail/serialize' require 'net/smtp' require 'socket' +require 'etc' -module Reporting - def self.report - begin - yield - rescue Exception => e - raise unless e.respond_to?(:target) - error(e) - exit(1) if e.fatal? +require 'autobuild/exceptions' + +module Autobuild + class Reporting + @@reporters = Array.new + + def self.report + begin + yield + rescue Autobuild::Exception => e + raise unless e.kind_of?(Autobuild::Exception) + error(e) + exit(1) if e.fatal? + end end - end - - def self.success - message = "Build finished successfully at #{Time.now}" - puts message - send_mail("Build success", message) if $MAIL - end + + def self.success + @@reporters.each do |rep| rep.success end + end - def self.error(object) - if object.kind_of?(SubcommandFailed) - body = <<EOF -#{object.target}: #{object.message} - command '#{object.command}' failed with status #{object.status} - see #{File.basename(object.logfile)} for details -EOF + def self.error(error) + @@reporters.each do |rep| rep.error(error) end + end - message = <<EOF -#{object.target}: #{object.message} - command '#{object.command}' failed with status #{object.status} - see #{object.logfile} for details -EOF - else - body = message = "#{object.target}: #{object.message}" + def self.<<(reporter) + @@reporters << reporter end - puts message - send_mail("Build failed", body) if $MAIL && object.mail? + def self.each_log(&iter) + Dir.glob("#{$LOGDIR}/*.log", &iter) + end end - private + class Reporter + def error(error); end + def success; end + end - def self.send_mail(subject, body) - from = ($MAIL[:from] || "autobuild@#{Socket.gethostname}") - to = $MAIL[:to] - smtp = ($MAIL[:smtp] || "localhost" ) + class StdoutReporter < Reporter + def error(error) + puts "Build failed: #{error}" + end + def success + puts "Build finished successfully at #{Time.now}" + end + end - mail = RMail::Message.new - mail.header.date = Time.now - mail.header.from = from - mail.header.to = to - mail.header.subject = subject + class MailReporter < Reporter + def default_mail + Etc::endpwent + uname = while (pwent = Etc::getpwent) + break (pwent.name) if pwent.uid == Process.uid + end - part = RMail::Message.new - part.header.set('Content-Type', 'text/plain') - part.body = body - mail.add_part(part) + raise "FATAL: cannot find a user with uid=#{Process.uid}" unless uname + "#{pwent.name}@#{Socket.gethostname}" + end + + def initialize(config) + @from = (config[:from] || default_mail) + @to = (config[:to] || default_mail) + @smtp = (config[:smtp] || "localhost" ) + @port = Integer(config[:port] || Socket.getservbyname('smtp')) + end - # Attach log files - Dir.glob("#{$LOGDIR}/*.log") do |file| - mail.add_file(file) + def error(error) + if error.mail? + send_mail("Build failed", error.to_s) + end end - # Send the mail - smtp = Net::SMTP.new(smtp, Integer($MAIL[:port] || 25)) - smtp.start { - smtp.send_mail RMail::Serialize.write('', mail), from, to - } + def success + send_mail("Build success", "finished successfully at #{Time.now}") + end + + def send_mail(subject, body) + mail = RMail::Message.new + mail.header.date = Time.now + mail.header.from = @from + mail.header.to = @to + mail.header.subject = subject + + part = RMail::Message.new + part.header.set('Content-Type', 'text/plain') + part.body = body + mail.add_part(part) + + # Attach log files + Reporting.each_log do |file| + mail.add_file(file) + end + + # Send the mail + smtp = Net::SMTP.new(@smtp, @port) + smtp.start { + smtp.send_mail RMail::Serialize.write('', mail), @from, @to + } + + # Notify the sending + puts "Sent notification mail to #{@to} with source #{@from}" + + end end end - module RMail class Message def add_file(path, content_type='text/plain') part = RMail::Message.new