propel 0.2.2 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile.lock +3 -1
- data/lib/propel.rb +1 -0
- data/lib/propel/configuration.rb +19 -5
- data/lib/propel/logger.rb +38 -0
- data/lib/propel/option_parser.rb +8 -4
- data/lib/propel/runner.rb +34 -24
- data/lib/propel/version.rb +1 -1
- data/propel.gemspec +1 -1
- data/spec/propel/configuration_spec.rb +1 -1
- data/spec/propel/logger_spec.rb +72 -0
- data/spec/propel/option_parser_spec.rb +4 -4
- data/spec/propel/runner_spec.rb +17 -19
- metadata +8 -5
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile.lock
CHANGED
data/lib/propel.rb
CHANGED
data/lib/propel/configuration.rb
CHANGED
@@ -1,19 +1,33 @@
|
|
1
1
|
module Propel
|
2
2
|
class Configuration
|
3
|
+
|
3
4
|
def initialize(command_line_arguments, repository)
|
4
5
|
@command_line_options = command_line_arguments
|
5
6
|
@repository = repository
|
6
7
|
end
|
7
8
|
|
8
9
|
DEFAULTS = {
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
10
|
+
:color => false,
|
11
|
+
:fix_ci => false,
|
12
|
+
:rebase => true,
|
13
|
+
:verbose => false,
|
14
|
+
:wait => false
|
13
15
|
}
|
14
16
|
|
15
17
|
def options
|
16
|
-
DEFAULTS.merge(parse(options_from_config_file).merge(parse @command_line_options))
|
18
|
+
opts = DEFAULTS.merge(parse(options_from_config_file).merge(parse @command_line_options))
|
19
|
+
correct_color_setting!(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def correct_color_setting!(opts)
|
23
|
+
if opts[:color_enabled] && RUBY_PLATFORM =~ /mswin|mingw/
|
24
|
+
unless ENV['ANSICON']
|
25
|
+
warn "You must use ANSICON 1.31 or later (http://adoxa.110mb.com/ansicon/) to use colour on Windows"
|
26
|
+
opts[:color] = false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
opts
|
17
31
|
end
|
18
32
|
|
19
33
|
def config_file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Propel
|
2
|
+
class Logger
|
3
|
+
COLORS = {
|
4
|
+
:red => 31,
|
5
|
+
:green => 32,
|
6
|
+
:yellow => 33,
|
7
|
+
}
|
8
|
+
|
9
|
+
def initialize(configuration)
|
10
|
+
@configuration = configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
def print(message, color_sym = nil)
|
14
|
+
unless @configuration[:quiet]
|
15
|
+
Kernel.print color(message, color_sym)
|
16
|
+
STDOUT.flush
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def puts(message, color_sym = nil)
|
21
|
+
Kernel.puts color(message, color_sym) unless @configuration[:quiet]
|
22
|
+
end
|
23
|
+
|
24
|
+
def warn(message, color_sym = nil)
|
25
|
+
Kernel.warn color(message, color_sym) unless @configuration[:quiet]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def color(message, color_sym)
|
31
|
+
if @configuration[:color] && color_sym
|
32
|
+
"\e[#{COLORS[color_sym]}m#{message}\e[0m"
|
33
|
+
else
|
34
|
+
message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/propel/option_parser.rb
CHANGED
@@ -25,16 +25,20 @@ module Propel
|
|
25
25
|
options[:fix_ci] = o
|
26
26
|
end
|
27
27
|
|
28
|
-
parser.on('-r', '--[no-]rebase', '
|
28
|
+
parser.on('-r', '--[no-]rebase', 'Use pull with --rebase. Rebase is used by default.') do |o|
|
29
29
|
options[:rebase] = o
|
30
30
|
end
|
31
31
|
|
32
|
-
parser.on('-
|
32
|
+
parser.on('-c', '--[no-]color', '--[no-]colour', 'Turn on or off colored output. Color is off by default.') do |o|
|
33
|
+
options[:color] = o
|
34
|
+
end
|
35
|
+
|
36
|
+
parser.on('-w', '--[no-]wait', 'Waits for fixes to remote build.') do |o|
|
33
37
|
options[:wait] = o
|
34
38
|
end
|
35
39
|
|
36
|
-
parser.on('-
|
37
|
-
options[:
|
40
|
+
parser.on('-q', '--[no-]quiet', 'Silences normal output messages.') do |o|
|
41
|
+
options[:quiet] = o
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
data/lib/propel/runner.rb
CHANGED
@@ -1,35 +1,51 @@
|
|
1
1
|
module Propel
|
2
2
|
class Runner
|
3
|
+
attr_reader :logger
|
4
|
+
|
3
5
|
def initialize(args = [ ])
|
4
6
|
@repository = GitRepository.new
|
5
|
-
@options
|
7
|
+
@options = Configuration.new(args, @repository).options
|
8
|
+
@logger = Logger.new(@options)
|
6
9
|
end
|
7
10
|
|
8
11
|
def start
|
9
12
|
if @repository.changed?
|
10
13
|
if remote_build_configured?
|
11
|
-
|
14
|
+
|
15
|
+
if @options[:fix_ci]
|
16
|
+
@logger.puts("Thanks for trying to fix the build!", :green)
|
17
|
+
else
|
18
|
+
check_remote_build!
|
19
|
+
end
|
12
20
|
|
13
21
|
else
|
14
|
-
|
22
|
+
@logger.warn "Remote build is not configured, you should point propel to the status URL of your CI server."
|
23
|
+
|
15
24
|
end
|
16
25
|
|
17
26
|
propel!
|
18
27
|
else
|
19
|
-
puts
|
28
|
+
@logger.puts("There is nothing to propel - your HEAD is identical to #{@repository.remote_config} #{@repository.merge_config}.", :green)
|
29
|
+
|
20
30
|
end
|
21
31
|
end
|
22
32
|
|
23
33
|
private
|
24
34
|
|
25
35
|
def check_remote_build!
|
26
|
-
|
36
|
+
@logger.print "CI server status:\t"
|
37
|
+
STDOUT.flush
|
38
|
+
|
39
|
+
waited_for_build = false
|
27
40
|
if @options[:wait]
|
28
41
|
unless remote_build_green?
|
29
|
-
|
30
|
-
|
42
|
+
waited_for_build = true
|
43
|
+
|
44
|
+
say_duration do
|
45
|
+
@logger.puts("FAILING", :red)
|
46
|
+
@logger.puts "Waiting until the CI build is green."
|
31
47
|
wait until remote_build_green?
|
32
|
-
puts
|
48
|
+
@logger.puts("\nThe CI build has been fixed.", :green)
|
33
49
|
end
|
34
50
|
end
|
35
51
|
|
@@ -38,41 +54,35 @@ module Propel
|
|
38
54
|
alert_broken_build_and_exit unless remote_build_green?
|
39
55
|
end
|
40
56
|
|
41
|
-
puts
|
57
|
+
@logger.puts("PASSING", :green) unless waited_for_build
|
42
58
|
end
|
43
59
|
|
44
|
-
def
|
60
|
+
def say_duration
|
45
61
|
start_time = Time.now
|
46
62
|
yield
|
47
63
|
end_time = Time.now
|
48
|
-
puts
|
49
|
-
end
|
50
|
-
|
51
|
-
def log_wait_notice
|
52
|
-
puts "The remote build is failing, waiting until it is green to proceed."
|
64
|
+
@logger.puts("We waited for #{(end_time - start_time).round} seconds while the build was failing.")
|
53
65
|
end
|
54
66
|
|
55
67
|
def alert_broken_build_and_exit
|
68
|
+
@logger.puts("FAILING", :red)
|
69
|
+
|
56
70
|
msg = <<-EOS
|
57
|
-
|
58
|
-
|
71
|
+
The remote build is broken. If your commit fixes the build, run propel with --fix-ci (-f).
|
72
|
+
If you're waiting for someone else to fix the build, use propel with --wait (-w).
|
59
73
|
EOS
|
60
74
|
|
61
|
-
|
75
|
+
@logger.puts("")
|
76
|
+
warn msg
|
62
77
|
exit 1
|
63
78
|
end
|
64
79
|
|
65
|
-
def fix_ci?
|
66
|
-
@options[:fix_ci]
|
67
|
-
end
|
68
|
-
|
69
80
|
def remote_build_configured?
|
70
81
|
!@options[:status_url].nil?
|
71
82
|
end
|
72
83
|
|
73
84
|
def wait
|
74
|
-
print
|
75
|
-
STDOUT.flush
|
85
|
+
@logger.print(".", :yellow)
|
76
86
|
sleep 5
|
77
87
|
end
|
78
88
|
|
data/lib/propel/version.rb
CHANGED
data/propel.gemspec
CHANGED
@@ -20,7 +20,7 @@ describe Propel::Configuration do
|
|
20
20
|
configuration = Propel::Configuration.new([], Propel::GitRepository.new)
|
21
21
|
configuration.stub!(:options_from_config_file).and_return([])
|
22
22
|
|
23
|
-
configuration.options.should == { :rebase => true, :fix_ci => false, :verbose => false, :wait => false}
|
23
|
+
configuration.options.should == { :rebase => true, :fix_ci => false, :verbose => false, :wait => false, :color => false }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Propel::Logger do
|
4
|
+
describe "#print" do
|
5
|
+
it "should print the message when quiet mode is disabled" do
|
6
|
+
logger = Propel::Logger.new({:quiet => false})
|
7
|
+
Kernel.should_receive(:print).with('Hi')
|
8
|
+
|
9
|
+
logger.print('Hi')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should not print the message when quiet mode is enabled" do
|
13
|
+
logger = Propel::Logger.new({:quiet => true})
|
14
|
+
Kernel.should_not_receive(:print).with('Hi')
|
15
|
+
|
16
|
+
logger.print('Hi')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should colorize the method when color is enabled and a color is provided" do
|
20
|
+
logger = Propel::Logger.new({:quiet => false, :color => true})
|
21
|
+
Kernel.should_receive(:print).with("\e[32mHi\e[0m")
|
22
|
+
|
23
|
+
logger.print('Hi', :green)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#puts" do
|
28
|
+
it "should puts the message when quiet mode is disabled" do
|
29
|
+
logger = Propel::Logger.new({:quiet => false})
|
30
|
+
Kernel.should_receive(:puts).with('Hi')
|
31
|
+
|
32
|
+
logger.puts('Hi')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not puts the message when quiet mode is enabled" do
|
36
|
+
logger = Propel::Logger.new({:quiet => true})
|
37
|
+
Kernel.should_not_receive(:puts).with('Hi')
|
38
|
+
|
39
|
+
logger.puts('Hi')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should colorize the method when color is enabled and a color is provided" do
|
43
|
+
logger = Propel::Logger.new({:quiet => false, :color => true})
|
44
|
+
Kernel.should_receive(:puts).with("\e[31mHi\e[0m")
|
45
|
+
|
46
|
+
logger.puts('Hi', :red)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#warn" do
|
51
|
+
it "should warn the message when quiet mode is disabled" do
|
52
|
+
logger = Propel::Logger.new({:quiet => false})
|
53
|
+
Kernel.should_receive(:warn).with('Hi')
|
54
|
+
|
55
|
+
logger.warn('Hi')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not warn the message when quiet mode is enabled" do
|
59
|
+
logger = Propel::Logger.new({:quiet => true})
|
60
|
+
Kernel.should_not_receive(:warn).with('Hi')
|
61
|
+
|
62
|
+
logger.warn('Hi')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should colorize the method when color is enabled and a color is provided" do
|
66
|
+
logger = Propel::Logger.new({:quiet => false, :color => true})
|
67
|
+
Kernel.should_receive(:warn).with("\e[33mHi\e[0m")
|
68
|
+
|
69
|
+
logger.warn('Hi', :yellow)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -10,14 +10,14 @@ describe Propel::OptionParser do
|
|
10
10
|
Propel::OptionParser.parse!(['--no-rebase'])[:rebase].should be_false
|
11
11
|
end
|
12
12
|
|
13
|
-
it "should set verbose to true when given as an option" do
|
14
|
-
Propel::OptionParser.parse!(['--verbose'])[:verbose].should be_true
|
15
|
-
end
|
16
|
-
|
17
13
|
it "should set wait to true when given as an option" do
|
18
14
|
Propel::OptionParser.parse!(['--wait'])[:wait].should be_true
|
19
15
|
end
|
20
16
|
|
17
|
+
it "should set quiet to true when given as an option" do
|
18
|
+
Propel::OptionParser.parse!(['--quiet'])[:quiet].should be_true
|
19
|
+
end
|
20
|
+
|
21
21
|
it "should set the status url based on the given parameters" do
|
22
22
|
Propel::OptionParser.parse!(['--status-url', 'http://ci.example.com/feed.rss'])[:status_url].
|
23
23
|
should == 'http://ci.example.com/feed.rss'
|
data/spec/propel/runner_spec.rb
CHANGED
@@ -9,15 +9,14 @@ describe Propel::Runner do
|
|
9
9
|
|
10
10
|
describe ".start" do
|
11
11
|
it "should not call propel! if there is nothing to push" do
|
12
|
-
runner = Propel::Runner.new
|
12
|
+
runner = Propel::Runner.new(%w[--quiet])
|
13
13
|
@git_repository.should_receive(:changed?).and_return(false)
|
14
14
|
runner.should_not_receive(:propel!)
|
15
|
-
runner.stub!(:puts)
|
16
15
|
runner.start
|
17
16
|
end
|
18
17
|
|
19
18
|
it "should call propel! if there are changes to the current branch" do
|
20
|
-
runner = Propel::Runner.new
|
19
|
+
runner = Propel::Runner.new(%w[--quiet])
|
21
20
|
|
22
21
|
@git_repository.stub!(:changed?).and_return(true)
|
23
22
|
@git_repository.stub!(:remote_config).and_return('origin')
|
@@ -28,34 +27,33 @@ describe Propel::Runner do
|
|
28
27
|
end
|
29
28
|
|
30
29
|
it "should call propel! if the remote build is configured and passing" do
|
31
|
-
runner = Propel::Runner.new(%w[ --status-url http://ci.example.com/status ])
|
30
|
+
runner = Propel::Runner.new(%w[ --status-url http://ci.example.com/status --quiet ])
|
31
|
+
|
32
32
|
runner.stub!(:remote_build_configured?).and_return(true)
|
33
33
|
runner.stub!(:remote_build_green?).and_return(true)
|
34
34
|
|
35
35
|
runner.should_receive(:propel!)
|
36
|
-
runner.should_receive(:puts).with("Checking remote build...")
|
37
|
-
runner.should_receive(:puts).with("Remote build is passing.")
|
38
36
|
runner.start
|
39
37
|
end
|
40
38
|
|
41
39
|
it "should call propel! if the remote build is not configured" do
|
42
|
-
runner = Propel::Runner.new
|
40
|
+
runner = Propel::Runner.new(%w[--quiet])
|
43
41
|
runner.stub!(:remote_build_configured?).and_return false
|
44
42
|
runner.should_receive(:propel!)
|
43
|
+
runner.logger.should_receive(:warn).with("Remote build is not configured, you should point propel to the status URL of your CI server.")
|
45
44
|
|
46
45
|
runner.start
|
47
46
|
end
|
48
47
|
|
49
48
|
class TestError < StandardError ; end
|
50
49
|
it "should send an alert about the broken build if the remote build is configured but not passing" do
|
51
|
-
runner = Propel::Runner.new
|
50
|
+
runner = Propel::Runner.new(%w[--quiet])
|
52
51
|
runner.stub!(:remote_build_configured?).and_return true
|
53
52
|
runner.stub!(:remote_build_green?).and_return false
|
54
53
|
|
55
54
|
runner.should_receive(:alert_broken_build_and_exit).and_raise(TestError.new("Execution should be aborted here"))
|
56
55
|
runner.should_not_receive(:propel!)
|
57
56
|
|
58
|
-
runner.should_receive(:puts).with("Checking remote build...")
|
59
57
|
lambda {
|
60
58
|
runner.start
|
61
59
|
}.should raise_error(TestError)
|
@@ -64,6 +62,7 @@ describe Propel::Runner do
|
|
64
62
|
it "should call propel! when the remote build is failing if --fix-ci is specified" do
|
65
63
|
runner = Propel::Runner.new %w[ --fix-ci ]
|
66
64
|
runner.stub!(:remote_build_configured?).and_return true
|
65
|
+
runner.logger.should_receive(:puts).with("Thanks for trying to fix the build!", :green)
|
67
66
|
runner.stub!(:remote_build_passing?).and_return false
|
68
67
|
runner.should_receive(:propel!)
|
69
68
|
|
@@ -74,14 +73,17 @@ describe Propel::Runner do
|
|
74
73
|
runner = Propel::Runner.new %w[ --fix-ci ]
|
75
74
|
runner.stub!(:remote_build_configured?).and_return false
|
76
75
|
|
76
|
+
runner.logger.should_receive(:warn).with("Remote build is not configured, you should point propel to the status URL of your CI server.")
|
77
77
|
runner.should_receive(:propel!)
|
78
78
|
|
79
79
|
runner.start
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should run a command using pull --rebase by default" do
|
83
|
-
runner = Propel::Runner.new
|
84
|
-
|
83
|
+
runner = Propel::Runner.new(%w[--quiet])
|
84
|
+
|
85
|
+
runner.logger.should_receive(:warn).with("Remote build is not configured, you should point propel to the status URL of your CI server.")
|
86
|
+
|
85
87
|
runner.should_receive(:system).with("git pull --rebase && rake && git push")
|
86
88
|
runner.start
|
87
89
|
end
|
@@ -89,23 +91,19 @@ describe Propel::Runner do
|
|
89
91
|
it "should run a command using pull without --rebase when --no-rebase is specified" do
|
90
92
|
runner = Propel::Runner.new(['--no-rebase'])
|
91
93
|
runner.should_receive(:system).with("git pull && rake && git push")
|
94
|
+
runner.logger.should_receive(:warn).with("Remote build is not configured, you should point propel to the status URL of your CI server.")
|
95
|
+
|
92
96
|
runner.start
|
93
97
|
end
|
94
98
|
|
95
99
|
it "should wait for the build to pass if the user specifies the --wait option" do
|
96
|
-
runner = Propel::Runner.new([
|
100
|
+
runner = Propel::Runner.new(%w[--wait --quiet])
|
97
101
|
runner.stub!(:remote_build_configured?).and_return true
|
98
102
|
|
99
103
|
runner.should_receive(:remote_build_green?).twice.and_return(false, true)
|
100
104
|
|
101
|
-
runner.should_receive(:
|
102
|
-
|
103
|
-
runner.should_receive(:wait_with_notice).and_yield
|
105
|
+
runner.should_receive(:say_duration).and_yield
|
104
106
|
|
105
|
-
runner.stub!(:puts)
|
106
|
-
runner.stub!(:print).with('.')
|
107
|
-
runner.stub!(:sleep).with(5)
|
108
|
-
|
109
107
|
runner.should_receive(:propel!)
|
110
108
|
runner.start
|
111
109
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: propel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Justin Leitgeb
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-03 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -59,6 +59,7 @@ extra_rdoc_files: []
|
|
59
59
|
|
60
60
|
files:
|
61
61
|
- .gitignore
|
62
|
+
- .rspec
|
62
63
|
- Gemfile
|
63
64
|
- Gemfile.lock
|
64
65
|
- LICENSE
|
@@ -68,6 +69,7 @@ files:
|
|
68
69
|
- lib/propel.rb
|
69
70
|
- lib/propel/configuration.rb
|
70
71
|
- lib/propel/git_repository.rb
|
72
|
+
- lib/propel/logger.rb
|
71
73
|
- lib/propel/option_parser.rb
|
72
74
|
- lib/propel/remote_build.rb
|
73
75
|
- lib/propel/runner.rb
|
@@ -81,6 +83,7 @@ files:
|
|
81
83
|
- spec/fixtures/team_city/passing_build.rss
|
82
84
|
- spec/propel/configuration_spec.rb
|
83
85
|
- spec/propel/git_repository_spec.rb
|
86
|
+
- spec/propel/logger_spec.rb
|
84
87
|
- spec/propel/option_parser_spec.rb
|
85
88
|
- spec/propel/remote_build_spec.rb
|
86
89
|
- spec/propel/runner_spec.rb
|