Browse files

initial commit

  • Loading branch information...
0 parents commit 24c9ab2ae17cd50c1d559c5c8f22a0da3d56f7c5 @svenfuchs svenfuchs committed Nov 29, 2011
21 Gemfile
@@ -0,0 +1,21 @@
+source :rubygems
+
+gem 'activesupport', '~> 3.1.3'
+gem 'hashr', '~> 0.0.18'
+gem 'multi_json', '~> 1.0.3'
+gem 'json'
+
+platform :jruby do
+ gem 'hot_bunnies', '~> 1.3.3'
+ gem 'net-ssh-shell', '~> 0.2.0'
+ gem 'jruby-openssl', '~> 0.7.4'
+end
+
+group :test do
+ gem 'rake', '~> 0.9.2'
+ gem 'mocha'
+ gem 'rspec'
+ gem 'simplecov', '>= 0.4.0', :require => false
+end
+
+
41 Gemfile.lock
@@ -0,0 +1,41 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activesupport (3.1.3)
+ multi_json (~> 1.0)
+ diff-lcs (1.1.3)
+ hashr (0.0.18)
+ json (1.6.2)
+ metaclass (0.0.1)
+ mocha (0.10.0)
+ metaclass (~> 0.0.1)
+ multi_json (1.0.4)
+ rake (0.9.2.2)
+ rspec (2.7.0)
+ rspec-core (~> 2.7.0)
+ rspec-expectations (~> 2.7.0)
+ rspec-mocks (~> 2.7.0)
+ rspec-core (2.7.1)
+ rspec-expectations (2.7.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.7.0)
+ simplecov (0.5.4)
+ multi_json (~> 1.0.3)
+ simplecov-html (~> 0.5.3)
+ simplecov-html (0.5.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ activesupport (~> 3.1.3)
+ hashr (~> 0.0.18)
+ hot_bunnies (~> 1.3.3)
+ jruby-openssl (~> 0.7.4)
+ json
+ mocha
+ multi_json (~> 1.0.3)
+ net-ssh-shell (~> 0.2.0)
+ rake (~> 0.9.2)
+ rspec
+ simplecov (>= 0.4.0)
21 LICENSE
@@ -0,0 +1,21 @@
+MIT LICENSE
+
+Copyright (c) Sven Fuchs <svenfuchs@artweb-design.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
1 README.md
@@ -0,0 +1 @@
+# travis-support
10 Rakefile
@@ -0,0 +1,10 @@
+require 'rake'
+require 'rake/testtask'
+
+Rake::TestTask.new do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = false
+end
+
+task :default => :test
16 lib/travis/support.rb
@@ -0,0 +1,16 @@
+module Travis
+ autoload :Assertions, 'travis/support/assertions'
+ autoload :Logging, 'travis/support/logging'
+ autoload :Retryable, 'travis/support/retryable'
+
+ class << self
+ def logger
+ @logger ||= Logging.configure(Logger.new(STDOUT))
+ end
+
+ def logger=(logger)
+ @logger = Logging.configure(logger)
+ end
+ end
+end
+
32 lib/travis/support/assertions.rb
@@ -0,0 +1,32 @@
+require 'active_support/core_ext/module/aliasing'
+
+module Travis
+ class AssertionFailed < RuntimeError
+ attr_reader :object, :method
+
+ def initialize(object = nil, method = nil)
+ @object = object
+ @method = method
+ end
+
+ def to_s
+ "#{object.inspect}##{method} did not return true."
+ end
+ end
+
+ module Assertions
+ def assert(name)
+ define_method(:"#{name}_with_assert") do |*args, &block|
+ send(:"#{name}_without_assert", *args, &block).tap do |result|
+ raise Travis::AssertionFailed.new(self, name) unless result
+ end
+ end
+ alias_method_chain name, 'assert'
+ end
+ end
+end
+
+class Module
+ def define_assertion(name)
+ end
+end
71 lib/travis/support/logging.rb
@@ -0,0 +1,71 @@
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/module/aliasing'
+require 'logger'
+
+module Travis
+ module Logging
+ autoload :Format, 'travis/support/logging/format'
+
+ class << self
+ def included(base)
+ base.extend(ClassMethods)
+ end
+
+ delegate :logger, :to => Travis
+
+ def configure(logger)
+ logger.tap do
+ logger.formatter = proc { |*args| Format.format(*args) }
+ logger.level = Logger.const_get(:debug.to_s.upcase) # TODO set from Travis::Worker.config or something
+ end
+ end
+
+ def before(type, *args)
+ logger.send(type || :info, Format.before(*args))
+ end
+
+ def after(type, *args)
+ logger.send(type || :debug, Format.after(*args))
+ end
+ end
+
+ delegate :logger, :to => Travis
+
+ [:fatal, :error, :warn, :info, :debug].each do |level|
+ define_method(level) do |*args|
+ message, options = *args
+ message.chomp.split("\n").each do |line|
+ logger.send(level, Logging::Format.wrap(self, line, options || {}))
+ end
+ end
+ end
+
+ def log_exception(exception)
+ logger.error(Logging::Format.wrap(self, "#{exception.class.name}: #{exception.message}"))
+ exception.backtrace.each do |line|
+ logger.error(Logging::Format.wrap(self, line))
+ end if exception.backtrace
+ end
+
+ def log_header
+ self.class.log_header ? instance_eval(&self.class.log_header) : self.class.name.split('::').last.downcase
+ end
+
+ module ClassMethods
+ def log_header(&block)
+ block ? @log_header = block : @log_header
+ end
+
+ def log(name, options = {})
+ define_method(:"#{name}_with_log") do |*args, &block|
+ arguments = options[:params].is_a?(FalseClass) ? [] : args
+ Logging.before(options[:as], self, name, arguments) unless options[:only] == :after
+ send(:"#{name}_without_log", *args, &block).tap do |result|
+ Logging.after(options[:as], self, name) unless options[:only] == :before
+ end
+ end
+ alias_method_chain name, 'log'
+ end
+ end
+ end
+end
44 lib/travis/support/logging/format.rb
@@ -0,0 +1,44 @@
+module Travis
+ module Logging
+ module Format
+ class << self
+ def format(severity, time, progname, msg)
+ "#{severity[0, 1]} [#{format_time(time)}] #{msg}\n"
+ end
+
+ def format_time(time)
+ time.strftime("%Y-%m-%d %H:%M:%S.") << time.usec.to_s[0, 3]
+ end
+
+ def before(object, name, args)
+ wrap(object, "about to #{name}#{self.arguments(args)}")
+ end
+
+ def after(object, name)
+ wrap(object, "done: #{name}")
+ end
+
+ def wrap(object, message, options = {})
+ header = options[:header] || object.log_header
+ "[#{header}] #{message.chomp}"
+ end
+
+ def exception(object, exception)
+ wrap(object, ([message] + backtrace).join("\n"))
+ end
+
+ def arguments(args)
+ args.empty? ? '' : "(#{args.map { |arg| self.argument(arg).inspect }.join(', ')})"
+ end
+
+ def argument(arg)
+ if arg.is_a?(Hash) && arg.key?(:log) && arg[:log].size > 80
+ arg = arg.dup
+ arg[:log] = "#{arg[:log][0..80]} ..."
+ end
+ arg
+ end
+ end
+ end
+ end
+end
26 lib/travis/support/retryable.rb
@@ -0,0 +1,26 @@
+module Travis
+ module Retryable
+ # Retries a given block a specified number of times in the
+ # event the specified exception is raised. If the retries
+ # run out, the final exception is raised.
+ #
+ # This code is adapted slightly from the following blog post:
+ # http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/
+ #
+ # This code is pretty much directly 'borrowed' from vagrant,
+ # a project which made Travis possible! :)
+ def retryable(opts=nil)
+ opts = { :tries => 1, :on => Exception }.merge(opts || {})
+
+ begin
+ return yield
+ rescue *opts[:on]
+ if (opts[:tries] -= 1) > 0
+ sleep opts[:sleep].to_f if opts[:sleep]
+ retry
+ end
+ raise
+ end
+ end
+ end
+end
1 lib/travis_support.rb
@@ -0,0 +1 @@
+require 'travis/support'
3 lib/travis_support/version.rb
@@ -0,0 +1,3 @@
+module TravisSupport
+ VERSION = "0.0.1"
+end
31 spec/assertions_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+require 'travis/support'
+
+describe Travis::Assertions do
+ class A
+ extend Travis::Assertions
+
+ def initialize(result)
+ @result = result
+ end
+
+ def the_method
+ @result
+ end
+ assert :the_method
+ end
+
+ subject { lambda { A.new(@return_value).the_method } }
+
+ describe 'an asserted method' do
+ it 'does not raise an exception when the returned values is true' do
+ @return_value = true
+ should_not raise_error(Travis::AssertionFailed)
+ end
+
+ it 'raises an exception when the returned values is false' do
+ @return_value = false
+ should raise_error(Travis::AssertionFailed)
+ end
+ end
+end
55 spec/logging_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+require 'travis/support'
+require 'stringio'
+require 'logger'
+
+describe Travis::Logging do
+ class Foo
+ include Travis::Logging
+
+ log_header { 'header' }
+
+ def do_something(*args)
+ end
+ log :do_something
+ end
+
+ let(:io) { StringIO.new }
+ let(:object) { Foo.new }
+
+ before :each do
+ Travis.logger = Logger.new(io)
+ end
+
+ describe '.log' do
+ it 'logs before the method call' do
+ object.do_something(:foo, :bar)
+ io.string.should include('about to do_something')
+ end
+
+ it 'logs after the method call' do
+ object.do_something(:foo, :bar)
+ io.string.should include('done: do_something')
+ end
+
+ it 'includes the log header' do
+ object.do_something(:foo, :bar)
+ io.string.should include('header')
+ end
+ end
+
+ describe 'log_exception' do
+ let(:exception) { Exception.new('kaputt!').tap { |e| e.set_backtrace(['line 1', 'line 2']) } }
+
+ it 'logs the exception message' do
+ object.log_exception(exception)
+ io.string.should include('kaputt!')
+ end
+
+ it 'logs the backtrace' do
+ object.log_exception(exception)
+ io.string.should include("line 1")
+ io.string.should include("line 2")
+ end
+ end
+end
16 spec/spec_helper.rb
@@ -0,0 +1,16 @@
+require 'rubygems'
+
+require 'rspec'
+require 'mocha'
+
+require 'logger'
+require 'stringio'
+require 'travis/support'
+
+RSpec.configure do |config|
+ config.mock_with :mocha
+
+ config.before :each do
+ Travis.logger = Logger.new(StringIO.new)
+ end
+end
19 travis-support.gemspec
@@ -0,0 +1,19 @@
+# encoding: utf-8
+
+$:.unshift File.expand_path('../lib', __FILE__)
+require 'travis_support/version'
+
+Gem::Specification.new do |s|
+ s.name = "travis-support"
+ s.version = TravisSupport::VERSION
+ s.authors = ['Sven Fuchs', 'Josh Kalderimis', 'Michael Klishin']
+ s.email = 'contact@travis-ci.org'
+ s.homepage = 'http://github.com/travis-ci/travis-support'
+ s.summary = "[summary]"
+ s.description = "[description]"
+
+ s.files = Dir['{lib/**/*,spec**/*,[A-Z]*}']
+ s.platform = Gem::Platform::RUBY
+ s.require_path = 'lib'
+ s.rubyforge_project = '[none]'
+end

0 comments on commit 24c9ab2

Please sign in to comment.