roxanne 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +131 -0
- data/Rakefile +9 -0
- data/bin/roxanne +16 -0
- data/config/config.yml +6 -0
- data/lib/roxanne/configuration/yaml.rb +46 -0
- data/lib/roxanne/configuration.rb +26 -0
- data/lib/roxanne/consumers.rb +19 -0
- data/lib/roxanne/gpio/publisher.rb +24 -0
- data/lib/roxanne/http/consumer.rb +33 -0
- data/lib/roxanne/http_support.rb +43 -0
- data/lib/roxanne/jenkins/consumer.rb +34 -0
- data/lib/roxanne/loop.rb +35 -0
- data/lib/roxanne/publishers.rb +2 -0
- data/lib/roxanne/server.rb +24 -0
- data/lib/roxanne/test/consumer.rb +17 -0
- data/lib/roxanne/test/publisher.rb +18 -0
- data/lib/roxanne/travis/consumer.rb +32 -0
- data/lib/roxanne/version.rb +3 -0
- data/lib/roxanne.rb +10 -0
- data/roxanne.gemspec +37 -0
- data/service/etc_init.d_roxanne +21 -0
- data/service/roxanne.sh +5 -0
- data/spec/roxanne/configuration/yaml_spec.rb +48 -0
- data/spec/roxanne/configuration_spec.rb +37 -0
- data/spec/roxanne/gpio/publisher_spec.rb +54 -0
- data/spec/roxanne/jenkins/consumer_spec.rb +31 -0
- data/spec/roxanne/loop_spec.rb +80 -0
- data/spec/roxanne/server_spec.rb +62 -0
- data/spec/roxanne/travis/consumer_spec.rb +46 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/yaml/defaults.yml +8 -0
- data/spec/yaml/full_blown.yml +12 -0
- metadata +280 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Configuration::YAML do
|
4
|
+
|
5
|
+
def spec_file(variation)
|
6
|
+
File.expand_path(File.join(File.dirname(__FILE__), '../../yaml', "#{variation}.yml"))
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'uses activation default settings' do
|
10
|
+
subject.new(spec_file('defaults')).tap do |config|
|
11
|
+
config.active_days.must_equal 1..5
|
12
|
+
config.timerange.must_equal 8..19
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'overrides activation settings' do
|
17
|
+
subject.new(spec_file('full_blown')).tap do |config|
|
18
|
+
config.active_days.must_equal 1..3
|
19
|
+
config.timerange.must_equal 9..18
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Roxanne::Spec
|
24
|
+
class Consumer
|
25
|
+
attr_accessor :consumer_opt
|
26
|
+
end
|
27
|
+
|
28
|
+
class Publisher
|
29
|
+
attr_accessor :publisher_opt
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'create consumers' do
|
34
|
+
subject.new(spec_file('defaults')).tap do |config|
|
35
|
+
config.consumers.size.must_equal 1
|
36
|
+
config.consumers.first.must_be_instance_of Roxanne::Spec::Consumer
|
37
|
+
config.consumers.first.consumer_opt.must_equal "some-value"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'create publisher' do
|
42
|
+
subject.new(spec_file('defaults')).tap do |config|
|
43
|
+
config.publisher.must_be_instance_of Roxanne::Spec::Publisher
|
44
|
+
config.publisher.publisher_opt.must_equal "another-value"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Configuration::Base do
|
4
|
+
|
5
|
+
after do
|
6
|
+
Timecop.return
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'initializes settings' do
|
10
|
+
subject.new.tap do |config|
|
11
|
+
config.publisher.must_be_nil
|
12
|
+
config.consumers.must_equal []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'is active when in specified days and time range' do
|
17
|
+
Timecop.travel(Time.local(2014, 3, 7, 19, 59, 59))
|
18
|
+
subject.new.activated.must_equal true
|
19
|
+
|
20
|
+
Timecop.travel(Time.local(2014, 3, 3, 8, 0, 0))
|
21
|
+
subject.new.activated.must_equal true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'is not active when out of specified days' do
|
25
|
+
Timecop.travel(Time.local(2014, 3, 8, 8, 0, 0))
|
26
|
+
subject.new.activated.must_equal false
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'is not active when out of time range' do
|
30
|
+
Timecop.travel(Time.local(2014, 3, 7, 20, 0, 0))
|
31
|
+
subject.new.activated.must_equal false
|
32
|
+
|
33
|
+
Timecop.travel(Time.local(2014, 3, 3, 7, 59, 59))
|
34
|
+
subject.new.activated.must_equal false
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
describe Roxanne::GPIO::Publisher do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@publisher = subject.new
|
5
|
+
@publisher.green_pin = 17
|
6
|
+
@publisher.orange_pin = 25
|
7
|
+
@publisher.red_pin = 22
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'disable gpio pins' do
|
11
|
+
expects_all_off
|
12
|
+
@publisher.disable
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets all pins to zero on nil status' do
|
16
|
+
expects_all_off
|
17
|
+
@publisher.push nil, nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'switch green pin to 1 on green status' do
|
21
|
+
expects_pin(@publisher.green_pin).expects(:value).with 1
|
22
|
+
expects_pin(@publisher.orange_pin).expects(:value).with 0
|
23
|
+
expects_pin(@publisher.red_pin).expects(:value).with 0
|
24
|
+
@publisher.push nil, :green
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'switch red pin to 1 on red status' do
|
28
|
+
expects_pin(@publisher.green_pin).expects(:value).with 0
|
29
|
+
expects_pin(@publisher.orange_pin).expects(:value).with 0
|
30
|
+
expects_pin(@publisher.red_pin).expects(:value).with 1
|
31
|
+
@publisher.push nil, :red
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'switch orange pin to 1 on orange status' do
|
35
|
+
expects_pin(@publisher.green_pin).expects(:value).with 0
|
36
|
+
expects_pin(@publisher.orange_pin).expects(:value).with 1
|
37
|
+
expects_pin(@publisher.red_pin).expects(:value).with 0
|
38
|
+
@publisher.push nil, :orange
|
39
|
+
end
|
40
|
+
|
41
|
+
def expects_pin(num)
|
42
|
+
mock.tap do |pin|
|
43
|
+
Taopaipai.gpio.expects(:pin).with(num, direction: :out).returns(pin)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def expects_all_off
|
48
|
+
[17, 25, 22].each do |num|
|
49
|
+
expects_pin(num).expects(:value).with(0)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Jenkins::Consumer do
|
4
|
+
|
5
|
+
def jobs(*colors)
|
6
|
+
{ 'jobs' => colors.map{|color| {'color'=>color} } }.to_json
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'defaults to green' do
|
10
|
+
subject.new.handle_response(jobs).must_equal :green
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'ignores unknown job colors' do
|
14
|
+
subject.new.handle_response(jobs('british_racing_green')).must_equal :green
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns green if all good' do
|
18
|
+
subject.new.handle_response(jobs('blue', 'yellow')).must_equal :green
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns orange if one of the jobs is orange' do
|
22
|
+
subject.new.handle_response(jobs('yellow_anime', 'blue', 'yellow')).must_equal :orange
|
23
|
+
subject.new.handle_response(jobs('blue_anime', 'blue', 'yellow')).must_equal :orange
|
24
|
+
subject.new.handle_response(jobs('red_anime', 'blue', 'yellow_anime')).must_equal :orange
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns red if one of the jobs is read' do
|
28
|
+
subject.new.handle_response(jobs('red', 'blue', 'yellow_anime')).must_equal :red
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Loop do
|
4
|
+
before do
|
5
|
+
@publisher = mock
|
6
|
+
@config = Roxanne::Configuration::Base.new
|
7
|
+
@config.stubs(:publisher).returns @publisher
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'disables publishers unless active' do
|
11
|
+
@config.expects(:activated).returns false
|
12
|
+
@publisher.expects(:disable)
|
13
|
+
subject.new(@config).cycle
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'activated' do
|
17
|
+
|
18
|
+
before do
|
19
|
+
@config.expects(:activated).at_least(1).returns true
|
20
|
+
@publisher.expects(:disable).never
|
21
|
+
|
22
|
+
3.times do
|
23
|
+
@config.consumers << mock
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'publishes green if all of consumers answer green' do
|
28
|
+
@config.consumers.each do |consumer|
|
29
|
+
consumer.expects(:pull).returns :green
|
30
|
+
end
|
31
|
+
@publisher.expects(:push).with(nil, :green)
|
32
|
+
subject.new(@config).cycle
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'publishes red if one of the consumers answers red' do
|
36
|
+
@config.consumers.first.expects(:pull).returns :red
|
37
|
+
@publisher.expects(:push).with(nil, :red)
|
38
|
+
subject.new(@config).cycle
|
39
|
+
end
|
40
|
+
|
41
|
+
def expects_pulls(*statuses)
|
42
|
+
@config.consumers.each_with_index do |consumer, i|
|
43
|
+
consumer.expects(:pull).returns statuses[i] if statuses[i]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'publishes orange if a consumer answers orange and the previous status wasnt green' do
|
48
|
+
loop = subject.new(@config)
|
49
|
+
# First cycle to turn it red
|
50
|
+
expects_pulls(:red)
|
51
|
+
@publisher.expects(:push).with(nil, :red)
|
52
|
+
loop.cycle
|
53
|
+
|
54
|
+
# Second cycle to orange
|
55
|
+
expects_pulls(:green, :orange, :green)
|
56
|
+
@publisher.expects(:push).with(:red, :orange)
|
57
|
+
loop.cycle
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'publishes green if orange and previous state wasnt red' do
|
61
|
+
loop = subject.new(@config)
|
62
|
+
|
63
|
+
expects_pulls(:green, :green, :green)
|
64
|
+
@publisher.expects(:push).with(nil, :green)
|
65
|
+
loop.cycle
|
66
|
+
|
67
|
+
expects_pulls(:orange, :green, :green)
|
68
|
+
@publisher.expects(:push).with(:green, :green)
|
69
|
+
loop.cycle
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'publishes nil on reset' do
|
75
|
+
loop = subject.new(@config)
|
76
|
+
@publisher.expects(:push).with(nil, nil)
|
77
|
+
loop.reset
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Server do
|
4
|
+
|
5
|
+
describe 'with a test double' do
|
6
|
+
class ServerDouble < Roxanne::Server
|
7
|
+
attr_reader :slept_for, :looped
|
8
|
+
|
9
|
+
def initialize(configuration, opts)
|
10
|
+
@config = configuration
|
11
|
+
super(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def loop(&block)
|
15
|
+
@looped = true
|
16
|
+
yield
|
17
|
+
end
|
18
|
+
|
19
|
+
def sleep(time)
|
20
|
+
@slept_for = time
|
21
|
+
end
|
22
|
+
|
23
|
+
def config(args)
|
24
|
+
@config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
@configuration = Roxanne::Configuration::Base.new
|
30
|
+
@server = ServerDouble.new(
|
31
|
+
@configuration,
|
32
|
+
working_dir: @working_dir = File.join(File.dirname(__FILE__), '../..')
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'logs, cycle and sleep' do
|
37
|
+
STDOUT.expects(:puts).with("Roxanne starting in #{@working_dir}")
|
38
|
+
controller = Roxanne::Loop.new(@configuration)
|
39
|
+
Roxanne::Loop.expects(:new).with(@configuration).returns(controller)
|
40
|
+
controller.expects(:cycle)
|
41
|
+
@server.start([])
|
42
|
+
@server.looped.must_equal true
|
43
|
+
@server.slept_for.must_equal 5
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'stops' do
|
47
|
+
@server.instance_variable_set(:@controller, controller = mock)
|
48
|
+
controller.expects(:reset)
|
49
|
+
@server.stop
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'creates a YAML configuration using the default path' do
|
54
|
+
Roxanne::Configuration::YAML.expects(:new).with('config/config.yml').returns(config = mock)
|
55
|
+
subject.new({working_dir: ''}).config([]).must_equal config
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'creates a YAML configuration using the provided path' do
|
59
|
+
Roxanne::Configuration::YAML.expects(:new).with('specific-config.yml').returns(config = mock)
|
60
|
+
subject.new({working_dir: ''}).config(['specific-config.yml']).must_equal config
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roxanne::Travis::Consumer do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@subject = subject.new
|
7
|
+
@subject.organization_or_user = 'servebox'
|
8
|
+
end
|
9
|
+
|
10
|
+
def expects_repositories_state( *repos )
|
11
|
+
mock_repos = repos.map do |repo|
|
12
|
+
mock.tap do |mock|
|
13
|
+
mock.stubs(:active?).returns(repo[:active].nil? ? true : repo[:active])
|
14
|
+
mock.stubs(:last_build_state).returns(repo[:build_state])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
Travis::Repository.expects(:find_all).with(owner_name: 'servebox').returns(mock_repos)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'defaults to green' do
|
21
|
+
expects_repositories_state
|
22
|
+
@subject.pull.must_equal :green
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'ignores inactive repositories' do
|
26
|
+
expects_repositories_state({ active: false, build_state: 'failed' })
|
27
|
+
@subject.pull.must_equal :green
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns green if all good' do
|
31
|
+
expects_repositories_state({ build_state: 'passed' })
|
32
|
+
@subject.pull.must_equal :green
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns orange if one of the jobs is orange' do
|
36
|
+
expects_repositories_state({ build_state: 'started' }, {build_state: 'passed'})
|
37
|
+
@subject.pull.must_equal :orange
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns red if one of the jobs is read' do
|
41
|
+
expects_repositories_state({ build_state: 'failed' }, { build_state: 'started' },
|
42
|
+
{build_state: 'passed'})
|
43
|
+
@subject.pull.must_equal :red
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#require 'simplecov'
|
2
|
+
#require 'coveralls'
|
3
|
+
#
|
4
|
+
#SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
5
|
+
# SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
# Coveralls::SimpleCov::Formatter
|
7
|
+
#]
|
8
|
+
#
|
9
|
+
#SimpleCov.start do
|
10
|
+
# add_filter '/spec/'
|
11
|
+
#end
|
12
|
+
|
13
|
+
require 'roxanne'
|
14
|
+
require 'minitest'
|
15
|
+
require 'minitest/spec'
|
16
|
+
require 'minitest/autorun'
|
17
|
+
require 'minitest/pride'
|
18
|
+
require 'minitest-implicit-subject'
|
19
|
+
require 'timecop'
|
20
|
+
require 'mocha/setup'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
roxanne:
|
2
|
+
activation:
|
3
|
+
days: !ruby/range 1..3
|
4
|
+
# Active from ~ 08:00 to 18:59
|
5
|
+
timerange: !ruby/range 9..18
|
6
|
+
consumers:
|
7
|
+
consumer_id:
|
8
|
+
class: "Roxanne::Spec::Consumer"
|
9
|
+
consumer_opt: "some-value"
|
10
|
+
publisher:
|
11
|
+
class: "Roxanne::Spec::Publisher"
|
12
|
+
publisher_opt: "another-value"
|
metadata
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roxanne
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jef Mathiot
|
8
|
+
- Patrice Izzo
|
9
|
+
- Fabrice Nourisson
|
10
|
+
- Benjamin Severac
|
11
|
+
- Eric Hartmann
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
date: 2014-04-03 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: json
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: daemon-spawn
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: activesupport
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 3.0.0
|
52
|
+
type: :runtime
|
53
|
+
prerelease: false
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 3.0.0
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: taopaipai
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - "~>"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.1.1
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - "~>"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 0.1.1
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: travis
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.6.8
|
80
|
+
type: :runtime
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.6.8
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: bundler
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.6'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '1.6'
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: rake
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: minitest
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 5.0.7
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 5.0.7
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: minitest-implicit-subject
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 1.4.0
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 1.4.0
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: rb-readline
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 0.5.0
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - "~>"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 0.5.0
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: guard-minitest
|
159
|
+
requirement: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: 2.1.3
|
164
|
+
type: :development
|
165
|
+
prerelease: false
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - "~>"
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: 2.1.3
|
171
|
+
- !ruby/object:Gem::Dependency
|
172
|
+
name: timecop
|
173
|
+
requirement: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
type: :development
|
179
|
+
prerelease: false
|
180
|
+
version_requirements: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
- !ruby/object:Gem::Dependency
|
186
|
+
name: mocha
|
187
|
+
requirement: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
type: :development
|
193
|
+
prerelease: false
|
194
|
+
version_requirements: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: '0'
|
199
|
+
description: 'Roxanne: publish your CI status to your device of choice'
|
200
|
+
email:
|
201
|
+
- foss@servebox.com
|
202
|
+
executables:
|
203
|
+
- roxanne
|
204
|
+
extensions: []
|
205
|
+
extra_rdoc_files: []
|
206
|
+
files:
|
207
|
+
- ".gitignore"
|
208
|
+
- ".ruby-version"
|
209
|
+
- ".travis.yml"
|
210
|
+
- Gemfile
|
211
|
+
- Guardfile
|
212
|
+
- LICENSE.txt
|
213
|
+
- README.md
|
214
|
+
- Rakefile
|
215
|
+
- bin/roxanne
|
216
|
+
- config/config.yml
|
217
|
+
- lib/roxanne.rb
|
218
|
+
- lib/roxanne/configuration.rb
|
219
|
+
- lib/roxanne/configuration/yaml.rb
|
220
|
+
- lib/roxanne/consumers.rb
|
221
|
+
- lib/roxanne/gpio/publisher.rb
|
222
|
+
- lib/roxanne/http/consumer.rb
|
223
|
+
- lib/roxanne/http_support.rb
|
224
|
+
- lib/roxanne/jenkins/consumer.rb
|
225
|
+
- lib/roxanne/loop.rb
|
226
|
+
- lib/roxanne/publishers.rb
|
227
|
+
- lib/roxanne/server.rb
|
228
|
+
- lib/roxanne/test/consumer.rb
|
229
|
+
- lib/roxanne/test/publisher.rb
|
230
|
+
- lib/roxanne/travis/consumer.rb
|
231
|
+
- lib/roxanne/version.rb
|
232
|
+
- roxanne.gemspec
|
233
|
+
- service/etc_init.d_roxanne
|
234
|
+
- service/roxanne.sh
|
235
|
+
- spec/roxanne/configuration/yaml_spec.rb
|
236
|
+
- spec/roxanne/configuration_spec.rb
|
237
|
+
- spec/roxanne/gpio/publisher_spec.rb
|
238
|
+
- spec/roxanne/jenkins/consumer_spec.rb
|
239
|
+
- spec/roxanne/loop_spec.rb
|
240
|
+
- spec/roxanne/server_spec.rb
|
241
|
+
- spec/roxanne/travis/consumer_spec.rb
|
242
|
+
- spec/spec_helper.rb
|
243
|
+
- spec/yaml/defaults.yml
|
244
|
+
- spec/yaml/full_blown.yml
|
245
|
+
homepage: http://github.com/servebox/roxanne
|
246
|
+
licenses:
|
247
|
+
- MIT
|
248
|
+
metadata: {}
|
249
|
+
post_install_message:
|
250
|
+
rdoc_options: []
|
251
|
+
require_paths:
|
252
|
+
- lib
|
253
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
254
|
+
requirements:
|
255
|
+
- - ">="
|
256
|
+
- !ruby/object:Gem::Version
|
257
|
+
version: '0'
|
258
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
|
+
requirements:
|
260
|
+
- - ">="
|
261
|
+
- !ruby/object:Gem::Version
|
262
|
+
version: '0'
|
263
|
+
requirements: []
|
264
|
+
rubyforge_project:
|
265
|
+
rubygems_version: 2.2.2
|
266
|
+
signing_key:
|
267
|
+
specification_version: 4
|
268
|
+
summary: Aggregate the status of Continuous Integration jobs or other sources and
|
269
|
+
publish them
|
270
|
+
test_files:
|
271
|
+
- spec/roxanne/configuration/yaml_spec.rb
|
272
|
+
- spec/roxanne/configuration_spec.rb
|
273
|
+
- spec/roxanne/gpio/publisher_spec.rb
|
274
|
+
- spec/roxanne/jenkins/consumer_spec.rb
|
275
|
+
- spec/roxanne/loop_spec.rb
|
276
|
+
- spec/roxanne/server_spec.rb
|
277
|
+
- spec/roxanne/travis/consumer_spec.rb
|
278
|
+
- spec/spec_helper.rb
|
279
|
+
- spec/yaml/defaults.yml
|
280
|
+
- spec/yaml/full_blown.yml
|