git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-09-14 15:56:09 +00:00
parent 3efe410dd0
commit 49a864ad90
23 changed files with 122 additions and 159 deletions

View File

@ -2,8 +2,14 @@ sudo: false
language: ruby language: ruby
script: script:
- bundle exec rspec - bundle exec rspec
rvm: matrix:
- 2.2.7 include:
- 2.3.4 - rvm: 2.2.7
- 2.4.1 - rvm: 2.3.4
- ruby-head - rvm: 2.4.1
- rvm: ruby-head
- jdk: oraclejdk8
install:
- curl -L https://github.com/graalvm/truffleruby/releases/download/vm-enterprise-0.27/truffleruby-testing-0.27.tar.gz | tar xz
- source truffleruby/setup_env
- bundle install

View File

@ -1,4 +1,4 @@
source 'https://rubygems.org' source 'https://rubygems.org'
# Specify your gem's dependencies in mspec.gemspec gem "rake", "~> 10.0"
gemspec gem "rspec", "~> 2.14.1"

View File

@ -1,8 +1,3 @@
PATH
remote: .
specs:
mspec (1.8.0)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
@ -22,9 +17,8 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
mspec!
rake (~> 10.0) rake (~> 10.0)
rspec (~> 2.14.1) rspec (~> 2.14.1)
BUNDLED WITH BUNDLED WITH
1.10.2 1.14.5

View File

@ -33,6 +33,9 @@ specs in a manner compatible with multiple Ruby implementations.
configuration facility with a default project file and user-specific configuration facility with a default project file and user-specific
overrides. overrides.
## Requirements
MSpec requires Ruby 2.2 or more recent.
## Bundler ## Bundler

View File

@ -5,16 +5,18 @@ class RaiseErrorMatcher
@exception = exception @exception = exception
@message = message @message = message
@block = block @block = block
@actual = nil
end end
def matches?(proc) def matches?(proc)
@result = proc.call @result = proc.call
return false return false
rescue Exception => @actual rescue Exception => actual
if matching_exception?(@actual) @actual = actual
if matching_exception?(actual)
return true return true
else else
raise @actual raise actual
end end
end end
@ -54,7 +56,7 @@ class RaiseErrorMatcher
def failure_message def failure_message
message = ["Expected #{format_expected_exception}"] message = ["Expected #{format_expected_exception}"]
if @actual then if @actual
message << "but got #{format_exception(@actual)}" message << "but got #{format_exception(@actual)}"
else else
message << "but no exception was raised (#{@result.pretty_inspect.chomp} was returned)" message << "but no exception was raised (#{@result.pretty_inspect.chomp} was returned)"

View File

@ -1,4 +1,5 @@
require 'mspec/expectations/expectations' require 'mspec/expectations/expectations'
require 'mspec/helpers/warning'
module Mock module Mock
def self.reset def self.reset
@ -57,10 +58,12 @@ module Mock
meta.__send__ :alias_method, key.first, sym meta.__send__ :alias_method, key.first, sym
end end
meta.class_eval { suppress_warning {
define_method(sym) do |*args, &block| meta.class_eval {
Mock.verify_call self, sym, *args, &block define_method(sym) do |*args, &block|
end Mock.verify_call self, sym, *args, &block
end
}
} }
proxy = MockProxy.new type proxy = MockProxy.new type
@ -179,7 +182,9 @@ module Mock
meta = obj.singleton_class meta = obj.singleton_class
if mock_respond_to? obj, replaced, true if mock_respond_to? obj, replaced, true
meta.__send__ :alias_method, sym, replaced suppress_warning do
meta.__send__ :alias_method, sym, replaced
end
meta.__send__ :remove_method, replaced meta.__send__ :remove_method, replaced
else else
meta.__send__ :remove_method, sym meta.__send__ :remove_method, sym

View File

@ -1,5 +1,4 @@
require 'mspec/runner/formatters/spinner' require 'mspec/runner/formatters/spinner'
require 'yaml'
class MultiFormatter < SpinnerFormatter class MultiFormatter < SpinnerFormatter
def initialize(out=nil) def initialize(out=nil)
@ -10,6 +9,8 @@ class MultiFormatter < SpinnerFormatter
end end
def aggregate_results(files) def aggregate_results(files)
require 'yaml'
@timer.finish @timer.finish
@exceptions = [] @exceptions = []

View File

@ -2,6 +2,9 @@ require 'mspec/runner/context'
require 'mspec/runner/exception' require 'mspec/runner/exception'
require 'mspec/runner/tag' require 'mspec/runner/tag'
module MSpec
end
class MSpecEnv class MSpecEnv
include MSpec include MSpec
end end
@ -399,4 +402,7 @@ module MSpec
file = tags_file file = tags_file
File.delete file if File.exist? file File.delete file if File.exist? file
end end
# Initialize @env
setup_env
end end

View File

@ -38,6 +38,10 @@ class MSpecScript
end end
def initialize def initialize
if RUBY_VERSION < '2.2'
abort "MSpec needs Ruby 2.2 or more recent"
end
config[:formatter] = nil config[:formatter] = nil
config[:includes] = [] config[:includes] = []
config[:excludes] = [] config[:excludes] = []

View File

@ -4,6 +4,7 @@ if RUBY_ENGINE == "ruby" and RUBY_VERSION >= "2.4.0"
ruby_version_is "2.4"..."2.5" do ruby_version_is "2.4"..."2.5" do
# Kernel#warn does not delegate to Warning.warn in 2.4 # Kernel#warn does not delegate to Warning.warn in 2.4
module Kernel module Kernel
remove_method :warn
def warn(*messages) def warn(*messages)
return if $VERBOSE == nil or messages.empty? return if $VERBOSE == nil or messages.empty?
msg = messages.join("\n") msg = messages.join("\n")
@ -16,6 +17,24 @@ if RUBY_ENGINE == "ruby" and RUBY_VERSION >= "2.4.0"
def Warning.warn(message) def Warning.warn(message)
case message case message
# $VERBOSE = true warnings
when /possibly useless use of (<|<=|==|>=|>|\+|-) in void context/
when /assigned but unused variable/
when /method redefined/
when /previous definition of/
when /instance variable @.+ not initialized/
when /statement not reached/
when /shadowing outer local variable/
when /setting Encoding.default_(in|ex)ternal/
when /unknown (un)?pack directive/
when /(un)?trust(ed\?)? is deprecated/
when /\.exists\? is a deprecated name/
when /Float .+ out of range/
when /passing a block to String#(bytes|chars|codepoints|lines) is deprecated/
when /core\/string\/modulo_spec\.rb:\d+: warning: too many arguments for format string/
when /regexp\/shared\/new_ascii(_8bit)?\.rb:\d+: warning: Unknown escape .+ is ignored/
# $VERBOSE = false warnings
when /constant ::(Fixnum|Bignum) is deprecated/ when /constant ::(Fixnum|Bignum) is deprecated/
when /\/(argf|io|stringio)\/.+(ARGF|IO)#(lines|chars|bytes|codepoints) is deprecated/ when /\/(argf|io|stringio)\/.+(ARGF|IO)#(lines|chars|bytes|codepoints) is deprecated/
when /Thread\.exclusive is deprecated.+\n.+thread\/exclusive_spec\.rb/ when /Thread\.exclusive is deprecated.+\n.+thread\/exclusive_spec\.rb/

View File

@ -1,40 +0,0 @@
# -*- encoding: utf-8 -*-
$:.unshift File.expand_path('../lib', __FILE__)
require 'mspec/version'
Gem::Specification.new do |gem|
gem.name = "mspec"
gem.version = MSpec::VERSION.to_s
gem.authors = ["Brian Shirai"]
gem.email = ["bshirai@engineyard.com"]
gem.homepage = "http://rubyspec.org"
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) unless File.extname(f) == ".bat" }.compact
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.require_paths = ["lib"]
gem.description = <<-EOD
MSpec is a specialized framework for RubySpec.
EOD
gem.summary = <<-EOS
MSpec is a specialized framework that is syntax-compatible
with RSpec for basic things like describe, it blocks and
before, after actions.
MSpec contains additional features that assist in writing
the RubySpecs used by multiple Ruby implementations. Also,
MSpec attempts to use the simplest Ruby language features
so that beginning Ruby implementations can run it.
EOS
gem.has_rdoc = true
gem.extra_rdoc_files = %w[ README.md LICENSE ]
gem.rubygems_version = %q{1.3.5}
gem.rubyforge_project = 'http://rubyforge.org/projects/mspec'
gem.rdoc_options << '--title' << 'MSpec Gem' <<
'--main' << 'README.md' <<
'--line-numbers'
gem.add_development_dependency "rake", "~> 10.0"
gem.add_development_dependency "rspec", "~> 2.14.1"
end

View File

@ -38,7 +38,7 @@ describe "The -b, --base DIR option" do
@options.stub(:on) @options.stub(:on)
@options.should_receive(:on).with("-b", "--base", "DIR", @options.should_receive(:on).with("-b", "--base", "DIR",
an_instance_of(String)) an_instance_of(String))
@script.options @script.options []
end end
it "sets the base directory relative to which the spec directories are created" do it "sets the base directory relative to which the spec directories are created" do
@ -62,7 +62,7 @@ describe "The -r, --require LIBRARY option" do
@options.stub(:on) @options.stub(:on)
@options.should_receive(:on).with("-r", "--require", "LIBRARY", @options.should_receive(:on).with("-r", "--require", "LIBRARY",
an_instance_of(String)) an_instance_of(String))
@script.options @script.options []
end end
it "adds CONSTANT to the list of constants" do it "adds CONSTANT to the list of constants" do
@ -86,7 +86,7 @@ describe "The -V, --version-guard VERSION option" do
@options.stub(:on) @options.stub(:on)
@options.should_receive(:on).with("-V", "--version-guard", "VERSION", @options.should_receive(:on).with("-V", "--version-guard", "VERSION",
an_instance_of(String)) an_instance_of(String))
@script.options @script.options []
end end
it "sets the version for the ruby_version_is guards to VERSION" do it "sets the version for the ruby_version_is guards to VERSION" do
@ -119,7 +119,7 @@ describe MkSpec, "#options" do
@options.should_receive(:raise).with(MSpecOptions::ParseError, an_instance_of(String)) @options.should_receive(:raise).with(MSpecOptions::ParseError, an_instance_of(String))
@options.stub(:puts) @options.stub(:puts)
@options.stub(:exit) @options.stub(:exit)
@script.options "--iunknown" @script.options ["--iunknown"]
end end
end end

View File

@ -15,17 +15,17 @@ describe MSpecCI, "#options" do
it "enables the chdir option" do it "enables the chdir option" do
@options.should_receive(:chdir) @options.should_receive(:chdir)
@script.options @script.options []
end end
it "enables the prefix option" do it "enables the prefix option" do
@options.should_receive(:prefix) @options.should_receive(:prefix)
@script.options @script.options []
end end
it "enables the config option" do it "enables the config option" do
@options.should_receive(:configure) @options.should_receive(:configure)
@script.options @script.options []
end end
it "provides a custom action (block) to the config option" do it "provides a custom action (block) to the config option" do
@ -35,52 +35,52 @@ describe MSpecCI, "#options" do
it "enables the dry run option" do it "enables the dry run option" do
@options.should_receive(:pretend) @options.should_receive(:pretend)
@script.options @script.options []
end end
it "enables the unguarded option" do it "enables the unguarded option" do
@options.should_receive(:unguarded) @options.should_receive(:unguarded)
@script.options @script.options []
end end
it "enables the interrupt single specs option" do it "enables the interrupt single specs option" do
@options.should_receive(:interrupt) @options.should_receive(:interrupt)
@script.options @script.options []
end end
it "enables the formatter options" do it "enables the formatter options" do
@options.should_receive(:formatters) @options.should_receive(:formatters)
@script.options @script.options []
end end
it "enables the verbose option" do it "enables the verbose option" do
@options.should_receive(:verbose) @options.should_receive(:verbose)
@script.options @script.options []
end end
it "enables the action options" do it "enables the action options" do
@options.should_receive(:actions) @options.should_receive(:actions)
@script.options @script.options []
end end
it "enables the action filter options" do it "enables the action filter options" do
@options.should_receive(:action_filters) @options.should_receive(:action_filters)
@script.options @script.options []
end end
it "enables the version option" do it "enables the version option" do
@options.should_receive(:version) @options.should_receive(:version)
@script.options @script.options []
end end
it "enables the help option" do it "enables the help option" do
@options.should_receive(:help) @options.should_receive(:help)
@script.options @script.options []
end end
it "calls #custom_options" do it "calls #custom_options" do
@script.should_receive(:custom_options).with(@options) @script.should_receive(:custom_options).with(@options)
@script.options @script.options []
end end
end end
@ -99,7 +99,7 @@ describe MSpecCI, "#run" do
@script.stub(:exit) @script.stub(:exit)
@script.stub(:config).and_return(@config) @script.stub(:config).and_return(@config)
@script.stub(:files).and_return(["one", "two"]) @script.stub(:files).and_return(["one", "two"])
@script.options @script.options []
end end
it "registers the tags patterns" do it "registers the tags patterns" do

View File

@ -4,12 +4,7 @@ require 'rbconfig'
describe SpecGuard, ".ruby_version" do describe SpecGuard, ".ruby_version" do
before :each do before :each do
@ruby_version = Object.const_get :RUBY_VERSION stub_const "RUBY_VERSION", "8.2.3"
Object.const_set :RUBY_VERSION, "8.2.3"
end
after :each do
Object.const_set :RUBY_VERSION, @ruby_version
end end
it "returns the full version for :full" do it "returns the full version for :full" do

View File

@ -2,27 +2,12 @@ require 'spec_helper'
require 'mspec/guards' require 'mspec/guards'
describe Object, "#not_supported_on" do describe Object, "#not_supported_on" do
before :all do
@verbose = $VERBOSE
$VERBOSE = nil
@ruby_engine = Object.const_get :RUBY_ENGINE if Object.const_defined? :RUBY_ENGINE
end
after :all do
$VERBOSE = @verbose
if @ruby_engine
Object.const_set :RUBY_ENGINE, @ruby_engine
else
Object.send :remove_const, :RUBY_ENGINE
end
end
before :each do before :each do
ScratchPad.clear ScratchPad.clear
end end
it "raises an Exception when passed :ruby" do it "raises an Exception when passed :ruby" do
Object.const_set :RUBY_ENGINE, "jruby" stub_const "RUBY_ENGINE", "jruby"
lambda { lambda {
not_supported_on(:ruby) { ScratchPad.record :yield } not_supported_on(:ruby) { ScratchPad.record :yield }
}.should raise_error(Exception) }.should raise_error(Exception)
@ -30,19 +15,19 @@ describe Object, "#not_supported_on" do
end end
it "does not yield when #implementation? returns true" do it "does not yield when #implementation? returns true" do
Object.const_set :RUBY_ENGINE, "jruby" stub_const "RUBY_ENGINE", "jruby"
not_supported_on(:jruby) { ScratchPad.record :yield } not_supported_on(:jruby) { ScratchPad.record :yield }
ScratchPad.recorded.should_not == :yield ScratchPad.recorded.should_not == :yield
end end
it "yields when #standard? returns true" do it "yields when #standard? returns true" do
Object.const_set :RUBY_ENGINE, "ruby" stub_const "RUBY_ENGINE", "ruby"
not_supported_on(:rubinius) { ScratchPad.record :yield } not_supported_on(:rubinius) { ScratchPad.record :yield }
ScratchPad.recorded.should == :yield ScratchPad.recorded.should == :yield
end end
it "yields when #implementation? returns false" do it "yields when #implementation? returns false" do
Object.const_set :RUBY_ENGINE, "jruby" stub_const "RUBY_ENGINE", "jruby"
not_supported_on(:rubinius) { ScratchPad.record :yield } not_supported_on(:rubinius) { ScratchPad.record :yield }
ScratchPad.recorded.should == :yield ScratchPad.recorded.should == :yield
end end

View File

@ -60,9 +60,9 @@ describe Object, "#new_fd" do
rm_r @name rm_r @name
end end
it "returns a Fixnum that can be used to create an IO instance" do it "returns a Integer that can be used to create an IO instance" do
fd = new_fd @name fd = new_fd @name
fd.should be_an_instance_of(Fixnum) fd.should be_kind_of(Integer)
@io = IO.new fd, fmode('w:utf-8') @io = IO.new fd, fmode('w:utf-8')
@io.sync = true @io.sync = true
@ -74,7 +74,7 @@ describe Object, "#new_fd" do
it "accepts an options Hash" do it "accepts an options Hash" do
FeatureGuard.stub(:enabled?).and_return(true) FeatureGuard.stub(:enabled?).and_return(true)
fd = new_fd @name, { :mode => 'w:utf-8' } fd = new_fd @name, { :mode => 'w:utf-8' }
fd.should be_an_instance_of(Fixnum) fd.should be_kind_of(Integer)
@io = IO.new fd, fmode('w:utf-8') @io = IO.new fd, fmode('w:utf-8')
@io.sync = true @io.sync = true

View File

@ -4,8 +4,8 @@ require 'mspec/matchers'
describe BeKindOfMatcher do describe BeKindOfMatcher do
it "matches when actual is a kind_of? expected" do it "matches when actual is a kind_of? expected" do
BeKindOfMatcher.new(Integer).matches?(1).should == true BeKindOfMatcher.new(Numeric).matches?(1).should == true
BeKindOfMatcher.new(Fixnum).matches?(2).should == true BeKindOfMatcher.new(Integer).matches?(2).should == true
BeKindOfMatcher.new(Regexp).matches?(/m/).should == true BeKindOfMatcher.new(Regexp).matches?(/m/).should == true
end end

View File

@ -2,13 +2,13 @@ require 'spec_helper'
require 'mspec/expectations/expectations' require 'mspec/expectations/expectations'
require 'mspec/matchers' require 'mspec/matchers'
class IVarModMock; end class IVarModMock
def self.class_variables
shared_examples_for "have_class_variable, on all Ruby versions" do [:@foo]
after :all do
Object.const_set :RUBY_VERSION, @ruby_version
end end
end
describe HaveClassVariableMatcher, "on RUBY_VERSION >= 1.9" do
it "matches when mod has the class variable, given as string" do it "matches when mod has the class variable, given as string" do
matcher = HaveClassVariableMatcher.new('@foo') matcher = HaveClassVariableMatcher.new('@foo')
matcher.matches?(IVarModMock).should be_true matcher.matches?(IVarModMock).should be_true
@ -47,16 +47,3 @@ shared_examples_for "have_class_variable, on all Ruby versions" do
] ]
end end
end end
describe HaveClassVariableMatcher, "on RUBY_VERSION >= 1.9" do
before :all do
@ruby_version = Object.const_get :RUBY_VERSION
Object.const_set :RUBY_VERSION, '1.9.0'
def IVarModMock.class_variables
[:@foo]
end
end
it_should_behave_like "have_class_variable, on all Ruby versions"
end

View File

@ -2,9 +2,12 @@ require 'spec_helper'
require 'mspec/expectations/expectations' require 'mspec/expectations/expectations'
require 'mspec/matchers' require 'mspec/matchers'
shared_examples_for "have_instance_variable, on all Ruby versions" do describe HaveInstanceVariableMatcher do
after :all do before :each do
Object.const_set :RUBY_VERSION, @ruby_version @object = Object.new
def @object.instance_variables
[:@foo]
end
end end
it "matches when object has the instance variable, given as string" do it "matches when object has the instance variable, given as string" do
@ -45,17 +48,3 @@ shared_examples_for "have_instance_variable, on all Ruby versions" do
] ]
end end
end end
describe HaveInstanceVariableMatcher, "on RUBY_VERSION >= 1.9" do
before :all do
@ruby_version = Object.const_get :RUBY_VERSION
Object.const_set :RUBY_VERSION, '1.9.0'
@object = Object.new
def @object.instance_variables
[:@foo]
end
end
it_should_behave_like "have_instance_variable, on all Ruby versions"
end

View File

@ -9,7 +9,7 @@ require 'mspec/runner/example'
describe ContextState, "#describe" do describe ContextState, "#describe" do
before :each do before :each do
@state = ContextState.new "C#m" @state = ContextState.new "C#m"
@proc = lambda {|*| ScratchPad.record :a } @proc = proc { ScratchPad.record :a }
ScratchPad.clear ScratchPad.clear
end end

View File

@ -58,8 +58,8 @@ end
describe MSpec, ".retrieve" do describe MSpec, ".retrieve" do
it "accesses .store'd data" do it "accesses .store'd data" do
MSpec.register :action, :first MSpec.register :retrieve, :first
MSpec.retrieve(:action).should == [:first] MSpec.retrieve(:retrieve).should == [:first]
end end
end end

View File

@ -48,7 +48,7 @@ def run_mspec(command, args)
ret = $? ret = $?
out = out.sub(/\A\$.+\n/, '') # Remove printed command line out = out.sub(/\A\$.+\n/, '') # Remove printed command line
out = out.sub(RUBY_DESCRIPTION, "RUBY_DESCRIPTION") out = out.sub(RUBY_DESCRIPTION, "RUBY_DESCRIPTION")
out = out.gsub(/\d\.\d{6}/, "D.DDDDDD") # Specs total time out = out.gsub(/\d+\.\d{6}/, "D.DDDDDD") # Specs total time
out = out.gsub(/\d{2}:\d{2}:\d{2}/, "00:00:00") # Progress bar time out = out.gsub(/\d{2}:\d{2}:\d{2}/, "00:00:00") # Progress bar time
out = out.gsub(cwd, "CWD") out = out.gsub(cwd, "CWD")
return out, ret return out, ret

View File

@ -20,17 +20,18 @@ IMPLS = {
MSPEC = ARGV.delete('--mspec') MSPEC = ARGV.delete('--mspec')
# Assuming the rubyspec repo is a sibling of the mspec repo MSPEC_REPO = File.expand_path("../../..", __FILE__)
RUBYSPEC_REPO = File.expand_path("../../../../rubyspec", __FILE__) raise MSPEC_REPO if !Dir.exist?(MSPEC_REPO) or !Dir.exist?("#{MSPEC_REPO}/.git")
raise RUBYSPEC_REPO unless Dir.exist?(RUBYSPEC_REPO)
MSPEC_REPO = File.expand_path("../../../../mspec", __FILE__) # Assuming the rubyspec repo is a sibling of the mspec repo
raise MSPEC_REPO if MSPEC && !Dir.exist?(MSPEC_REPO) RUBYSPEC_REPO = File.expand_path("../rubyspec", MSPEC_REPO)
raise RUBYSPEC_REPO unless Dir.exist?(RUBYSPEC_REPO)
SOURCE_REPO = MSPEC ? MSPEC_REPO : RUBYSPEC_REPO SOURCE_REPO = MSPEC ? MSPEC_REPO : RUBYSPEC_REPO
NOW = Time.now NOW = Time.now
BRIGHT_RED = "\e[31;1m"
BRIGHT_YELLOW = "\e[33;1m" BRIGHT_YELLOW = "\e[33;1m"
RESET = "\e[0m" RESET = "\e[0m"
@ -123,8 +124,14 @@ def rebase_commits(impl)
rebased = impl.rebased_branch rebased = impl.rebased_branch
if branch?(rebased) if branch?(rebased)
puts "#{BRIGHT_YELLOW}#{rebased} already exists, assuming it correct#{RESET}" last_commit = Time.at(Integer(`git log -n 1 --format='%ct' #{rebased}`))
sh "git", "checkout", rebased days_since_last_commit = (NOW-last_commit) / 86400
if days_since_last_commit > 7
abort "#{BRIGHT_RED}#{rebased} exists but last commit is old (#{last_commit}), delete the branch if it was merged#{RESET}"
else
puts "#{BRIGHT_YELLOW}#{rebased} already exists, last commit on #{last_commit}, assuming it correct#{RESET}"
sh "git", "checkout", rebased
end
else else
sh "git", "checkout", impl.name sh "git", "checkout", impl.name
@ -141,7 +148,7 @@ def rebase_commits(impl)
commit_date = Time.at(Integer(commit_timestamp)) commit_date = Time.at(Integer(commit_timestamp))
days_since_last_merge = (NOW-commit_date) / 86400 days_since_last_merge = (NOW-commit_date) / 86400
if days_since_last_merge > 60 if days_since_last_merge > 60
raise "#{days_since_last_merge} since last merge, probably wrong commit" raise "#{days_since_last_merge.floor} days since last merge, probably wrong commit"
end end
puts "Rebasing..." puts "Rebasing..."