extreme_feedback_device 0.0.1
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 +17 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +114 -0
- data/Rakefile +26 -0
- data/bin/extreme_feedback_device +17 -0
- data/bin/extreme_feedback_device_control +10 -0
- data/extreme_feedback_device.gemspec +34 -0
- data/lib/extreme_feedback_device/cli.rb +145 -0
- data/lib/extreme_feedback_device/jenkins.rb +47 -0
- data/lib/extreme_feedback_device/job.rb +52 -0
- data/lib/extreme_feedback_device/pi.rb +45 -0
- data/lib/extreme_feedback_device/settings.rb +8 -0
- data/lib/extreme_feedback_device/spi.rb +28 -0
- data/lib/extreme_feedback_device/version.rb +3 -0
- data/lib/extreme_feedback_device.rb +77 -0
- data/spec/extreme_feedback_device.yml +17 -0
- data/spec/lib/extreme_feedback_device/cli_spec.rb +64 -0
- data/spec/lib/extreme_feedback_device/jenkins_spec.rb +67 -0
- data/spec/lib/extreme_feedback_device/job_spec.rb +91 -0
- data/spec/lib/extreme_feedback_device_spec.rb +34 -0
- data/spec/spec_helper.rb +22 -0
- data/vendor/init.d/extreme_feedback_device +109 -0
- data/vendor/misc/application_cards.odt +0 -0
- metadata +237 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc66bca37d672e1868415f67627fd756c0a099a7
|
4
|
+
data.tar.gz: b027ef7580a3bcb5d052779bdf181487fef01899
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 944e3f32b1118fd3a18250cae2b3d0b308f4b575c804277e81f751e2aea5937b09a2ecc19e08d9076bcf99f92ccae75c92794f1c51a442b47c1b24254e4e24ee
|
7
|
+
data.tar.gz: b327e0f4da0a3f12e32cc79de0e8d20b411d2ce46d1337055962607cf26ef2b915f88853b033e8e4189d17361e48e879ca57e08bc7b4b5c5d12779150ff51aed
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
efd
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# ExtremeFeedbackDevice
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
Fetches Jobs from a Jenkins CI via the REST JSON API and sets LEDs of an Extreme Feedback Device to the status of the corresponding Job.
|
6
|
+
|
7
|
+
Tested with Ruby v2.0.0p247 running on Raspberry Pi with Raspbian "wheezy" / Debian GNU/Linux 7 "wheezy".
|
8
|
+
|
9
|
+
## Prepare
|
10
|
+
|
11
|
+
To get read-write permissions for the SPI-Device with udev you can add the following rule:
|
12
|
+
|
13
|
+
# /etc/udev/rules.d/99-spidev.rules
|
14
|
+
SUBSYSTEM=="spidev", GROUP="spidev", MODE="0660"
|
15
|
+
|
16
|
+
For this you first need to create a group spidev _(as root)_:
|
17
|
+
|
18
|
+
$ groupadd spidev
|
19
|
+
|
20
|
+
Add your user to the new group _(as root)_:
|
21
|
+
|
22
|
+
$ adduser foo spidev
|
23
|
+
|
24
|
+
After this, do a restart or run the following commands _(as root)_:
|
25
|
+
|
26
|
+
$ udevadm control --reload-rules
|
27
|
+
$ udevadm trigger --subsystem-match=spidev
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
Add this line to your application's Gemfile:
|
32
|
+
|
33
|
+
gem 'extreme_feedback_device'
|
34
|
+
|
35
|
+
And then execute:
|
36
|
+
|
37
|
+
$ bundle
|
38
|
+
|
39
|
+
Or install it yourself as:
|
40
|
+
|
41
|
+
$ gem install extreme_feedback_device
|
42
|
+
|
43
|
+
## Settings
|
44
|
+
|
45
|
+
TODO: Write configuration instruction here
|
46
|
+
|
47
|
+
The default location for the settings file is: `$HOME/.extreme_feedback_device.yml`
|
48
|
+
|
49
|
+
* `jenkins.*`: ...
|
50
|
+
* `infiniti_loop.sleep`: the time _(in seconds)_ to sleep between each request.
|
51
|
+
* `pi.num_leds`: the number of LEDs on your attached Extreme Feedback Device.
|
52
|
+
* `pi.map_leds`: the mapping of LEDs _(with LED's index)_ to Jenkins Jobs _(with Job's name)_.
|
53
|
+
* `spi.devive`: the SPI Device to write on.
|
54
|
+
|
55
|
+
### Example
|
56
|
+
|
57
|
+
default:
|
58
|
+
jenkins:
|
59
|
+
user: api
|
60
|
+
token: 0123456789ABCDEF
|
61
|
+
url: http://jenkins.example.com/
|
62
|
+
infiniti_loop:
|
63
|
+
sleep: 5
|
64
|
+
pi:
|
65
|
+
num_leds: 2
|
66
|
+
map_leds:
|
67
|
+
i_1: Jenkins - Master
|
68
|
+
i_0: Jenkins - Production
|
69
|
+
spi:
|
70
|
+
device: /dev/spidev0.0
|
71
|
+
|
72
|
+
## Usage
|
73
|
+
|
74
|
+
Output of `extreme_feedback_device --help`:
|
75
|
+
|
76
|
+
extreme_feedback_device [OPTION] ...
|
77
|
+
|
78
|
+
-h, --help:
|
79
|
+
show help.
|
80
|
+
|
81
|
+
-m, --mode [run]:
|
82
|
+
set mode 'run' for a single run or 'loop' for infiniti loop.
|
83
|
+
|
84
|
+
-n, --namespace [default]:
|
85
|
+
settings namespace.
|
86
|
+
|
87
|
+
-p, --pid [~/.extreme_feedback_device.pid]:
|
88
|
+
pid file.
|
89
|
+
|
90
|
+
-s, --settings [~/.extreme_feedback_device.yml]:
|
91
|
+
settings file.
|
92
|
+
|
93
|
+
-v, --version:
|
94
|
+
show version.
|
95
|
+
|
96
|
+
## Daemon
|
97
|
+
|
98
|
+
Copy the example init.d script and change it for your needs _(as root)_:
|
99
|
+
|
100
|
+
$ cp `gem contents extreme_feedback_device | grep vendor/init.d/extreme_feedback_device` /etc/init.d/extreme_feedback_device
|
101
|
+
$ chmod u+x /etc/init.d/extreme_feedback_device
|
102
|
+
$ vim /etc/init.d/extreme_feedback_device
|
103
|
+
|
104
|
+
If you want to start the daemon automaticaly on boot _(as root)_:
|
105
|
+
|
106
|
+
$ update-rc.d extreme_feedback_device defaults
|
107
|
+
|
108
|
+
## Contributing
|
109
|
+
|
110
|
+
1. Fork it
|
111
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
112
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
113
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
114
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
task :test => :spec
|
8
|
+
|
9
|
+
|
10
|
+
task :environment do
|
11
|
+
require 'extreme_feedback_device'
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :pi do
|
15
|
+
namespace :leds do
|
16
|
+
desc "turn all LEDs off / black"
|
17
|
+
task off: [:environment] do
|
18
|
+
ExtremeFeedbackDevice.pi.leds_black!
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "turn all LEDs on / white"
|
22
|
+
task on: [:environment] do
|
23
|
+
ExtremeFeedbackDevice.pi.leds_white!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if ENV['EFD_ENV'] == 'development'
|
4
|
+
lib = File.expand_path('../../lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
|
7
|
+
require 'pry'
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'extreme_feedback_device'
|
12
|
+
rescue LoadError
|
13
|
+
require 'rubygems'
|
14
|
+
require 'extreme_feedback_device'
|
15
|
+
end
|
16
|
+
|
17
|
+
ExtremeFeedbackDevice::CLI.instance.main
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'extreme_feedback_device/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "extreme_feedback_device"
|
8
|
+
spec.version = ExtremeFeedbackDevice::VERSION
|
9
|
+
spec.authors = ["Michael Nowak"]
|
10
|
+
spec.email = ["nowak@taktsoft.com"]
|
11
|
+
spec.summary = %q{Sets LEDs of an Extreme Feedback Device to a Status of a Job in Jenkins}
|
12
|
+
spec.summary = "Fetches Jobs from a Jenkins CI via the REST JSON API and sets LEDs of an Extreme Feedback Device to the status of the corresponding Job."
|
13
|
+
spec.description = "#{spec.summary} Build and designed for running on a Raspberry Pi with Debian 7."
|
14
|
+
spec.homepage = "https://github.com/taktsoft/#{spec.name}"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "color", "~> 1.4"
|
23
|
+
spec.add_dependency "daemons", "~> 1.1"
|
24
|
+
spec.add_dependency "settingslogic", "~> 2.0"
|
25
|
+
spec.add_dependency "pidfile", "~> 0.3"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "guard-rspec", "~> 2.5"
|
29
|
+
spec.add_development_dependency "pry", "~> 0.9"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.1"
|
31
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
32
|
+
spec.add_development_dependency "rb-fsevent", "~> 0.9"
|
33
|
+
spec.add_development_dependency "rb-inotify", "~> 0.9"
|
34
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'getoptlong'
|
2
|
+
require 'pidfile'
|
3
|
+
|
4
|
+
module ExtremeFeedbackDevice
|
5
|
+
class CLI
|
6
|
+
DEFAULT_MODE = 'run'
|
7
|
+
DEFAULT_NAMESPACE = 'default'
|
8
|
+
DEFAULT_PID = '~/.extreme_feedback_device.pid'
|
9
|
+
DEFAULT_SETTINGS = '~/.extreme_feedback_device.yml'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def instance
|
13
|
+
@instance ||= new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :opts, :pid_file
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@opts = ::GetoptLong.new(
|
21
|
+
[ '--help', '-h', ::GetoptLong::NO_ARGUMENT ],
|
22
|
+
[ '--mode', '-m', ::GetoptLong::REQUIRED_ARGUMENT ],
|
23
|
+
[ '--namespace', '-n', ::GetoptLong::REQUIRED_ARGUMENT ],
|
24
|
+
[ '--pid', '-p', ::GetoptLong::REQUIRED_ARGUMENT ],
|
25
|
+
[ '--settings', '-s', ::GetoptLong::REQUIRED_ARGUMENT ],
|
26
|
+
[ '--version', '-v', ::GetoptLong::NO_ARGUMENT ]
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def mode
|
31
|
+
@mode || DEFAULT_MODE
|
32
|
+
end
|
33
|
+
|
34
|
+
def namespace
|
35
|
+
@namespace || DEFAULT_NAMESPACE
|
36
|
+
end
|
37
|
+
|
38
|
+
def pid
|
39
|
+
@pid || DEFAULT_PID # File.expand_path(@pid || DEFAULT_PID)
|
40
|
+
end
|
41
|
+
|
42
|
+
def settings
|
43
|
+
@settings || DEFAULT_SETTINGS # File.expand_path(@settings || DEFAULT_SETTINGS)
|
44
|
+
end
|
45
|
+
|
46
|
+
def main
|
47
|
+
parse_opts!
|
48
|
+
|
49
|
+
if argv.length > 0
|
50
|
+
puts_help
|
51
|
+
exit -1
|
52
|
+
else
|
53
|
+
@pid_file = PidFile.new(piddir: File.expand_path(pid_dir), pidfile: pid_name)
|
54
|
+
|
55
|
+
ExtremeFeedbackDevice::Settings.source(File.expand_path(settings))
|
56
|
+
ExtremeFeedbackDevice::Settings.namespace(namespace)
|
57
|
+
ExtremeFeedbackDevice::Settings.reload!
|
58
|
+
|
59
|
+
if mode =~ /^run$/i
|
60
|
+
ExtremeFeedbackDevice.run
|
61
|
+
exit 0
|
62
|
+
elsif mode =~ /^loop$/i
|
63
|
+
ExtremeFeedbackDevice.infiniti_loop
|
64
|
+
exit 0
|
65
|
+
else
|
66
|
+
puts_help
|
67
|
+
exit -1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def argv
|
75
|
+
ARGV
|
76
|
+
end
|
77
|
+
|
78
|
+
def pid_dir
|
79
|
+
File.dirname(pid)
|
80
|
+
end
|
81
|
+
|
82
|
+
def pid_name
|
83
|
+
File.basename(pid)
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_opts!
|
87
|
+
begin
|
88
|
+
opts.each do |opt, arg|
|
89
|
+
case opt
|
90
|
+
when '--help'
|
91
|
+
puts_help
|
92
|
+
exit 0
|
93
|
+
when '--mode'
|
94
|
+
@mode = arg
|
95
|
+
when '--namespace'
|
96
|
+
@namespace = arg
|
97
|
+
when '--pid'
|
98
|
+
@pid = arg
|
99
|
+
when '--settings'
|
100
|
+
@settings = arg
|
101
|
+
when '--version'
|
102
|
+
puts_version
|
103
|
+
exit 0
|
104
|
+
end
|
105
|
+
end
|
106
|
+
rescue ::GetoptLong::Error => error
|
107
|
+
puts # linebreak
|
108
|
+
puts_help
|
109
|
+
exit -1
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def puts_help
|
114
|
+
puts <<-EOS
|
115
|
+
extreme_feedback_device [OPTION] ...
|
116
|
+
|
117
|
+
-h, --help:
|
118
|
+
\tshow help.
|
119
|
+
|
120
|
+
-m, --mode [#{DEFAULT_MODE}]:
|
121
|
+
\tset mode 'run' for a single run or 'loop' for infiniti loop.
|
122
|
+
|
123
|
+
-n, --namespace [#{DEFAULT_NAMESPACE}]:
|
124
|
+
\tsettings namespace.
|
125
|
+
|
126
|
+
-p, --pid [#{DEFAULT_PID}]:
|
127
|
+
\tpid file.
|
128
|
+
|
129
|
+
-s, --settings [#{DEFAULT_SETTINGS}]:
|
130
|
+
\tsettings file.
|
131
|
+
|
132
|
+
-v, --version:
|
133
|
+
\tshow version.
|
134
|
+
|
135
|
+
EOS
|
136
|
+
end
|
137
|
+
|
138
|
+
def puts_version
|
139
|
+
puts <<-EOS
|
140
|
+
extreme_feedback_device v#{ExtremeFeedbackDevice::VERSION}
|
141
|
+
|
142
|
+
EOS
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require "extreme_feedback_device/job"
|
5
|
+
|
6
|
+
module ExtremeFeedbackDevice
|
7
|
+
class Jenkins < ::Struct.new(:user, :token, :base_url)
|
8
|
+
def full_url
|
9
|
+
::File.join(base_url, 'api', 'json?tree=jobs[name,color,healthReport[score]]')
|
10
|
+
end
|
11
|
+
|
12
|
+
def full_uri
|
13
|
+
URI(full_url)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_json
|
17
|
+
request = ::Net::HTTP::Get.new(full_uri)
|
18
|
+
request.basic_auth(user, token)
|
19
|
+
|
20
|
+
response = ::Net::HTTP.start(full_uri.hostname, full_uri.port) do |http|
|
21
|
+
http.request(request)
|
22
|
+
end
|
23
|
+
|
24
|
+
if response.is_a?(::Net::HTTPSuccess)
|
25
|
+
response.body
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def jobs
|
32
|
+
jobs_from_json(get_json)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def jobs_from_json(json)
|
38
|
+
json_objects = []
|
39
|
+
begin
|
40
|
+
json_objects = ::JSON.parse(json)
|
41
|
+
rescue ::JSON::JSONError
|
42
|
+
end
|
43
|
+
|
44
|
+
json_objects["jobs"].map { |json_object| ExtremeFeedbackDevice::Job.from_json_object(json_object) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ExtremeFeedbackDevice
|
2
|
+
class Job < ::Struct.new(:name, :color, :health)
|
3
|
+
# http://buildsystem.bonn.taktsoft.com/api/schema
|
4
|
+
COLOR_RED = /\Ared/
|
5
|
+
COLOR_YELLOW = /\Ayellow/
|
6
|
+
COLOR_BLUE = /\Ablue/
|
7
|
+
COLOR_GREY = /\Agrey/
|
8
|
+
COLOR_DISABLED = /\Adisabled/
|
9
|
+
COLOR_ABORTED = /\Aaborted/
|
10
|
+
COLOR_NOTBUILT = /\Anotbuilt/
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def from_json_object(attributes)
|
14
|
+
health_report = attributes['healthReport']
|
15
|
+
attributes['score'] = health_report.first.nil? ? nil : health_report.first['score']
|
16
|
+
new(attributes['name'], attributes['color'], attributes['score'])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_hash
|
21
|
+
{name: name, color: color, health: health}
|
22
|
+
end
|
23
|
+
|
24
|
+
def fail?
|
25
|
+
color && color =~ COLOR_RED
|
26
|
+
end
|
27
|
+
|
28
|
+
def unstable?
|
29
|
+
color && color =~ COLOR_YELLOW
|
30
|
+
end
|
31
|
+
|
32
|
+
def success?
|
33
|
+
color && color =~ COLOR_BLUE
|
34
|
+
end
|
35
|
+
|
36
|
+
def inactive?
|
37
|
+
color && color =~ COLOR_GREY
|
38
|
+
end
|
39
|
+
|
40
|
+
def disabled?
|
41
|
+
color && color =~ COLOR_DISABLED
|
42
|
+
end
|
43
|
+
|
44
|
+
def aborted?
|
45
|
+
color && color =~ COLOR_ABORTED
|
46
|
+
end
|
47
|
+
|
48
|
+
def not_built?
|
49
|
+
color && color =~ COLOR_NOTBUILT
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'color'
|
2
|
+
|
3
|
+
require "extreme_feedback_device/spi"
|
4
|
+
|
5
|
+
module ExtremeFeedbackDevice
|
6
|
+
class Pi
|
7
|
+
attr_reader :leds
|
8
|
+
|
9
|
+
def initialize(num_leds, spi_device=nil)
|
10
|
+
@leds = []
|
11
|
+
num_leds.times { @leds << ::Color::RGB.new }
|
12
|
+
@spi_device = spi_device
|
13
|
+
end
|
14
|
+
|
15
|
+
def leds_white
|
16
|
+
leds.map! { |led| ::Color::RGB::White }
|
17
|
+
end
|
18
|
+
|
19
|
+
def leds_white!
|
20
|
+
leds_white && write!
|
21
|
+
end
|
22
|
+
|
23
|
+
def leds_black
|
24
|
+
leds.map! { |led| ::Color::RGB::Black }
|
25
|
+
end
|
26
|
+
|
27
|
+
def leds_black!
|
28
|
+
leds_black && write!
|
29
|
+
end
|
30
|
+
|
31
|
+
def write!
|
32
|
+
spi.write_colors(colors)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def spi
|
38
|
+
@spi ||= ExtremeFeedbackDevice::SPI.new(@spi_device)
|
39
|
+
end
|
40
|
+
|
41
|
+
def colors
|
42
|
+
leds.map { |led| [led.red, led.green, led.blue] }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ExtremeFeedbackDevice
|
2
|
+
class SPI
|
3
|
+
DEFAULT_DEVICE = '/dev/spidev0.0'
|
4
|
+
|
5
|
+
attr_reader :device
|
6
|
+
|
7
|
+
def initialize(device=nil)
|
8
|
+
@device = device || DEFAULT_DEVICE
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(data)
|
12
|
+
::File.open(device, 'wb') do |spi|
|
13
|
+
spi.write(data)
|
14
|
+
spi.flush
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_colors(colors)
|
19
|
+
write(colors_to_data(colors))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def colors_to_data(colors)
|
25
|
+
colors.flatten.pack('CCC' * colors.length)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
require "extreme_feedback_device/version"
|
5
|
+
|
6
|
+
module ExtremeFeedbackDevice
|
7
|
+
class << self
|
8
|
+
def logger
|
9
|
+
if settings['log']
|
10
|
+
@logger ||= ::Logger.new(settings.log.file, settings.log['keep'], settings.log['size'])
|
11
|
+
else
|
12
|
+
@logger ||= ::Logger.new(STDOUT)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def settings
|
17
|
+
@settings ||= ExtremeFeedbackDevice::Settings
|
18
|
+
end
|
19
|
+
|
20
|
+
def jenkins
|
21
|
+
@jenkins ||= ExtremeFeedbackDevice::Jenkins.new(settings.jenkins.user, settings.jenkins.token, settings.jenkins.url)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pi
|
25
|
+
@pi ||= ExtremeFeedbackDevice::Pi.new(settings.pi.num_leds, settings.spi['device'])
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
jobs = jenkins.jobs
|
30
|
+
num_leds = settings.pi.num_leds
|
31
|
+
map_leds = settings.pi.map_leds
|
32
|
+
|
33
|
+
num_leds.times do |led_idx|
|
34
|
+
job_name = map_leds["i_#{led_idx}"]
|
35
|
+
if job_name
|
36
|
+
job = jobs.find { |job| job.name == job_name }
|
37
|
+
if job
|
38
|
+
if job.fail?
|
39
|
+
pi.leds[led_idx] = ::Color::RGB::Red
|
40
|
+
elsif job.unstable?
|
41
|
+
pi.leds[led_idx] = ::Color::RGB::Yellow
|
42
|
+
elsif job.success?
|
43
|
+
pi.leds[led_idx] = ::Color::RGB::Green
|
44
|
+
elsif job.inactive?
|
45
|
+
pi.leds[led_idx] = ::Color::RGB::Grey
|
46
|
+
elsif job.disabled?
|
47
|
+
pi.leds[led_idx] = ::Color::RGB::Grey
|
48
|
+
else # any other state
|
49
|
+
pi.leds[led_idx] = ::Color::RGB::Black
|
50
|
+
end
|
51
|
+
else # no job with this name in jenkins
|
52
|
+
pi.leds[led_idx] = ::Color::RGB::Black
|
53
|
+
end
|
54
|
+
else # no job associated with this led_idx
|
55
|
+
pi.leds[led_idx] = ::Color::RGB::Black
|
56
|
+
end
|
57
|
+
end
|
58
|
+
pi.write!
|
59
|
+
end
|
60
|
+
|
61
|
+
def infiniti_loop
|
62
|
+
settings['infiniti_loop'] ||= {}
|
63
|
+
interval = settings.infiniti_loop['sleep'] || 30
|
64
|
+
while true
|
65
|
+
run
|
66
|
+
sleep(interval)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
require "extreme_feedback_device/cli"
|
73
|
+
require "extreme_feedback_device/jenkins"
|
74
|
+
require "extreme_feedback_device/job"
|
75
|
+
require "extreme_feedback_device/pi"
|
76
|
+
require "extreme_feedback_device/settings"
|
77
|
+
require "extreme_feedback_device/spi"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
default: &default
|
2
|
+
jenkins:
|
3
|
+
user: api
|
4
|
+
token: 0123456789ABCDEF
|
5
|
+
url: http://jenkins.example.com/
|
6
|
+
infiniti_loop:
|
7
|
+
sleep: 5
|
8
|
+
pi:
|
9
|
+
num_leds: 2
|
10
|
+
map_leds:
|
11
|
+
i_1: Jenkins - Master
|
12
|
+
i_0: Jenkins - Production
|
13
|
+
spi:
|
14
|
+
device: /dev/spidev0.0
|
15
|
+
|
16
|
+
test:
|
17
|
+
<<: *default
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'extreme_feedback_device'
|
3
|
+
|
4
|
+
describe ExtremeFeedbackDevice::CLI do
|
5
|
+
context "#instance" do
|
6
|
+
it "returns an instance of CLI" do
|
7
|
+
ExtremeFeedbackDevice::CLI.instance.should be_a ExtremeFeedbackDevice::CLI
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context ".main" do
|
12
|
+
before(:each) do
|
13
|
+
ExtremeFeedbackDevice.stub(:run)
|
14
|
+
ExtremeFeedbackDevice.stub(:infiniti_loop)
|
15
|
+
PidFile.stub(:new)
|
16
|
+
|
17
|
+
subject.stub(:argv).and_return([])
|
18
|
+
subject.stub(:parse_opts!)
|
19
|
+
subject.stub(:puts_help)
|
20
|
+
subject.stub(:puts_version)
|
21
|
+
subject.stub(:exit)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "calls parse_opts!" do
|
25
|
+
subject.should_receive(:parse_opts!)
|
26
|
+
subject.main
|
27
|
+
end
|
28
|
+
|
29
|
+
it "exits with null by default" do
|
30
|
+
subject.should_receive(:exit).with(0)
|
31
|
+
subject.main
|
32
|
+
end
|
33
|
+
|
34
|
+
it "calls ExtremeFeedbackDevice.run by default" do
|
35
|
+
ExtremeFeedbackDevice.should_receive(:run)
|
36
|
+
ExtremeFeedbackDevice.should_not_receive(:infiniti_loop)
|
37
|
+
subject.main
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context ".mode" do
|
42
|
+
it "returns default value if not set" do
|
43
|
+
subject.mode.should eql ExtremeFeedbackDevice::CLI::DEFAULT_MODE
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context ".namespace" do
|
48
|
+
it "returns default value if not set" do
|
49
|
+
subject.namespace.should eql ExtremeFeedbackDevice::CLI::DEFAULT_NAMESPACE
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context ".pid" do
|
54
|
+
it "returns default value if not set" do
|
55
|
+
subject.pid.should eql ExtremeFeedbackDevice::CLI::DEFAULT_PID
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context ".settings" do
|
60
|
+
it "returns default value if not set" do
|
61
|
+
subject.settings.should eql ExtremeFeedbackDevice::CLI::DEFAULT_SETTINGS
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'extreme_feedback_device/jenkins'
|
3
|
+
|
4
|
+
describe ExtremeFeedbackDevice::Jenkins do
|
5
|
+
context ".user" do
|
6
|
+
it "responds to user" do
|
7
|
+
subject.should be_respond_to "user"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "responds to user=" do
|
11
|
+
subject.should be_respond_to "user="
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context ".token" do
|
16
|
+
it "responds to token" do
|
17
|
+
subject.should be_respond_to "token"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to token=" do
|
21
|
+
subject.should be_respond_to "token="
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context ".base_url" do
|
26
|
+
it "responds to base_url" do
|
27
|
+
subject.should be_respond_to "base_url"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "responds to base_url=" do
|
31
|
+
subject.should be_respond_to "base_url="
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context ".full_url" do
|
36
|
+
it "joins parts correctly" do
|
37
|
+
subject.base_url = "http://localhost/"
|
38
|
+
subject.full_url.should eql "http://localhost/api/json?tree=jobs[name,color,healthReport[score]]"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context ".full_uri" do
|
43
|
+
it "returns an URI" do
|
44
|
+
subject.base_url = "http://localhost/"
|
45
|
+
subject.full_uri.should be_a URI
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context ".jobs" do
|
50
|
+
context "with mocked JSON" do
|
51
|
+
let(:response) { '''{"jobs":[
|
52
|
+
{"name":"Project X - Master","color":"blue","healthReport":[{"score":80}]},
|
53
|
+
{"name":"Project X - Production","color":"blue","healthReport":[{"score":60}]},
|
54
|
+
{"name":"Project Y - Master","color":"blue","healthReport":[{"score":100}]},
|
55
|
+
{"name":"Project Y - Production","color":"blue","healthReport":[{"score":40}]}
|
56
|
+
]}''' }
|
57
|
+
|
58
|
+
before(:each) do
|
59
|
+
subject.stub(:get_json).and_return(response)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns exactly four jobs" do
|
63
|
+
subject.jobs.should have(4).items
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'extreme_feedback_device/job'
|
3
|
+
|
4
|
+
describe ExtremeFeedbackDevice::Job do
|
5
|
+
context ".name" do
|
6
|
+
it "responds to name" do
|
7
|
+
subject.should be_respond_to "name"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "responds to name=" do
|
11
|
+
subject.should be_respond_to "name="
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context ".color" do
|
16
|
+
it "responds to color" do
|
17
|
+
subject.should be_respond_to "color"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to color=" do
|
21
|
+
subject.should be_respond_to "color="
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context ".fail?" do
|
26
|
+
it "returns correct answer" do
|
27
|
+
subject.color = 'red'
|
28
|
+
subject.should be_fail
|
29
|
+
subject.color = 'red_anime'
|
30
|
+
subject.should be_fail
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context ".unstable?" do
|
35
|
+
it "returns correct answer" do
|
36
|
+
subject.color = 'yellow'
|
37
|
+
subject.should be_unstable
|
38
|
+
subject.color = 'yellow_anime'
|
39
|
+
subject.should be_unstable
|
40
|
+
end
|
41
|
+
end
|
42
|
+
context ".success?" do
|
43
|
+
it "returns correct answer" do
|
44
|
+
subject.color = 'blue'
|
45
|
+
subject.should be_success
|
46
|
+
subject.color = 'blue_anime'
|
47
|
+
subject.should be_success
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context ".disabled?" do
|
52
|
+
it "returns correct answer" do
|
53
|
+
subject.color = 'disabled'
|
54
|
+
subject.should be_disabled
|
55
|
+
subject.color = 'disabled_anime'
|
56
|
+
subject.should be_disabled
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context ".health" do
|
61
|
+
it "responds to health" do
|
62
|
+
subject.should be_respond_to "health"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "responds to health=" do
|
66
|
+
subject.should be_respond_to "health="
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "#from_json_object" do
|
71
|
+
let(:klass) { ExtremeFeedbackDevice::Job }
|
72
|
+
let(:json_object) { {"name"=>"Project X - Master", "color"=>"blue", "healthReport"=>[{"score"=>80}]} }
|
73
|
+
|
74
|
+
it "sets attributes correctly" do
|
75
|
+
subject = klass.from_json_object(json_object)
|
76
|
+
subject.should be_a klass
|
77
|
+
subject.name.should eql "Project X - Master"
|
78
|
+
subject.color.should eql "blue"
|
79
|
+
subject.health.should eql 80
|
80
|
+
end
|
81
|
+
|
82
|
+
it "doesn't raise error if healthReport is empty" do
|
83
|
+
json_object["healthReport"].clear
|
84
|
+
subject = klass.from_json_object(json_object)
|
85
|
+
subject.should be_a klass
|
86
|
+
subject.name.should eql "Project X - Master"
|
87
|
+
subject.color.should eql "blue"
|
88
|
+
subject.health.should eql nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'extreme_feedback_device'
|
3
|
+
|
4
|
+
describe ExtremeFeedbackDevice do
|
5
|
+
context "#logger" do
|
6
|
+
it "returns a Logger" do
|
7
|
+
ExtremeFeedbackDevice.logger.should be_a ::Logger
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#settings" do
|
12
|
+
it "returns a ExtremeFeedbackDevice::Settings" do
|
13
|
+
ExtremeFeedbackDevice.settings.should be_a ::Class
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "#jenkins" do
|
18
|
+
it "returns a ExtremeFeedbackDevice::Jenkins" do
|
19
|
+
ExtremeFeedbackDevice.jenkins.should be_a ExtremeFeedbackDevice::Jenkins
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#pi" do
|
24
|
+
it "returns a ExtremeFeedbackDevice::Pi" do
|
25
|
+
ExtremeFeedbackDevice.pi.should be_a ExtremeFeedbackDevice::Pi
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "#run" do
|
30
|
+
end
|
31
|
+
|
32
|
+
context "#loop" do
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
ENV["EFD_YML"] ||= File.expand_path('../extreme_feedback_device.yml', __FILE__)
|
4
|
+
ENV["EFD_NS"] ||= 'test'
|
5
|
+
|
6
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
7
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
8
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
9
|
+
# loaded once.
|
10
|
+
#
|
11
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.filter_run :focus
|
16
|
+
|
17
|
+
# Run specs in random order to surface order dependencies. If you find an
|
18
|
+
# order dependency and want to debug it, you can fix the order by providing
|
19
|
+
# the seed, which is printed after each run.
|
20
|
+
# --seed 1234
|
21
|
+
config.order = 'random'
|
22
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
### BEGIN INIT INFO
|
3
|
+
# Provides: extreme_feedback_device
|
4
|
+
# Required-Start: $local_fs $remote_fs $network $syslog
|
5
|
+
# Required-Stop: $local_fs $remote_fs $network $syslog
|
6
|
+
# Default-Start: 2 3 4 5
|
7
|
+
# Default-Stop: 0 1 6
|
8
|
+
# Short-Description: Extreme Feedback Device -- Control
|
9
|
+
### END INIT INFO
|
10
|
+
|
11
|
+
DESC="Extreme Feedback Device -- Control"
|
12
|
+
NAME=extreme_feedback_device
|
13
|
+
SCRIPTNAME=/etc/init.d/$NAME
|
14
|
+
DAEMON=extreme_feedback_device_control
|
15
|
+
USER=foo
|
16
|
+
VERBOSE=yes
|
17
|
+
|
18
|
+
# Define LSB log_* functions.
|
19
|
+
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present
|
20
|
+
. /lib/lsb/init-functions
|
21
|
+
|
22
|
+
#
|
23
|
+
# Function that starts the daemon/service
|
24
|
+
#
|
25
|
+
do_start ()
|
26
|
+
{
|
27
|
+
su - ${USER} -c "${DAEMON} start -- --mode loop" | grep "running \[pid" >/dev/null
|
28
|
+
|
29
|
+
[ "$?" -gt 0 ] && return 0
|
30
|
+
return 1
|
31
|
+
}
|
32
|
+
|
33
|
+
#
|
34
|
+
# Function that stops the daemon/service
|
35
|
+
#
|
36
|
+
do_stop()
|
37
|
+
{
|
38
|
+
su - ${USER} -c "${DAEMON} stop" | grep "successfully stopped" >/dev/null
|
39
|
+
|
40
|
+
[ "$?" -gt 0 ] && return 1
|
41
|
+
return 0
|
42
|
+
}
|
43
|
+
|
44
|
+
#
|
45
|
+
# Function that asks status of the daemon/service
|
46
|
+
#
|
47
|
+
do_status()
|
48
|
+
{
|
49
|
+
su - ${USER} -c "${DAEMON} status" | grep "running \[pid" >/dev/null
|
50
|
+
|
51
|
+
[ "$?" -gt 0 ] && return 3
|
52
|
+
return 0
|
53
|
+
}
|
54
|
+
|
55
|
+
case "$1" in
|
56
|
+
start)
|
57
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
58
|
+
do_status
|
59
|
+
case "$?" in
|
60
|
+
3)
|
61
|
+
do_start
|
62
|
+
ENDVAL="$?"
|
63
|
+
;;
|
64
|
+
0)
|
65
|
+
ENDVAL="0"
|
66
|
+
;;
|
67
|
+
*)
|
68
|
+
ENDVAL="1"
|
69
|
+
;;
|
70
|
+
esac
|
71
|
+
[ "$VERBOSE" != no ] && log_end_msg $ENDVAL
|
72
|
+
;;
|
73
|
+
stop)
|
74
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
75
|
+
do_status
|
76
|
+
case "$?" in
|
77
|
+
3)
|
78
|
+
ENDVAL="0"
|
79
|
+
;;
|
80
|
+
0)
|
81
|
+
do_stop
|
82
|
+
ENDVAL="$?"
|
83
|
+
;;
|
84
|
+
*)
|
85
|
+
ENDVAL="1"
|
86
|
+
;;
|
87
|
+
esac
|
88
|
+
[ "$VERBOSE" != no ] && log_end_msg $ENDVAL
|
89
|
+
;;
|
90
|
+
status)
|
91
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Status $DESC" "$NAME"
|
92
|
+
do_status
|
93
|
+
[ "$VERBOSE" != no ] && log_end_msg $?
|
94
|
+
;;
|
95
|
+
restart)
|
96
|
+
[ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME"
|
97
|
+
do_stop
|
98
|
+
case "$?" in
|
99
|
+
0)
|
100
|
+
do_start
|
101
|
+
;;
|
102
|
+
esac
|
103
|
+
[ "$VERBOSE" != no ] && log_end_msg $?
|
104
|
+
;;
|
105
|
+
*)
|
106
|
+
echo "Usage: $SCRIPTNAME {start|stop|restart|status}" >&2
|
107
|
+
exit 3
|
108
|
+
;;
|
109
|
+
esac
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: extreme_feedback_device
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Nowak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: color
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: daemons
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: settingslogic
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pidfile
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.3'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.9'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '10.1'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '10.1'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.14'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.14'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rb-fsevent
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ~>
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.9'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ~>
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.9'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rb-inotify
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ~>
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.9'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ~>
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.9'
|
167
|
+
description: Fetches Jobs from a Jenkins CI via the REST JSON API and sets LEDs of
|
168
|
+
an Extreme Feedback Device to the status of the corresponding Job. Build and designed
|
169
|
+
for running on a Raspberry Pi with Debian 7.
|
170
|
+
email:
|
171
|
+
- nowak@taktsoft.com
|
172
|
+
executables:
|
173
|
+
- extreme_feedback_device
|
174
|
+
- extreme_feedback_device_control
|
175
|
+
extensions: []
|
176
|
+
extra_rdoc_files: []
|
177
|
+
files:
|
178
|
+
- .gitignore
|
179
|
+
- .rspec
|
180
|
+
- .ruby-gemset
|
181
|
+
- .ruby-version
|
182
|
+
- Gemfile
|
183
|
+
- Guardfile
|
184
|
+
- LICENSE.txt
|
185
|
+
- README.md
|
186
|
+
- Rakefile
|
187
|
+
- bin/extreme_feedback_device
|
188
|
+
- bin/extreme_feedback_device_control
|
189
|
+
- extreme_feedback_device.gemspec
|
190
|
+
- lib/extreme_feedback_device.rb
|
191
|
+
- lib/extreme_feedback_device/cli.rb
|
192
|
+
- lib/extreme_feedback_device/jenkins.rb
|
193
|
+
- lib/extreme_feedback_device/job.rb
|
194
|
+
- lib/extreme_feedback_device/pi.rb
|
195
|
+
- lib/extreme_feedback_device/settings.rb
|
196
|
+
- lib/extreme_feedback_device/spi.rb
|
197
|
+
- lib/extreme_feedback_device/version.rb
|
198
|
+
- spec/extreme_feedback_device.yml
|
199
|
+
- spec/lib/extreme_feedback_device/cli_spec.rb
|
200
|
+
- spec/lib/extreme_feedback_device/jenkins_spec.rb
|
201
|
+
- spec/lib/extreme_feedback_device/job_spec.rb
|
202
|
+
- spec/lib/extreme_feedback_device_spec.rb
|
203
|
+
- spec/spec_helper.rb
|
204
|
+
- vendor/init.d/extreme_feedback_device
|
205
|
+
- vendor/misc/application_cards.odt
|
206
|
+
homepage: https://github.com/taktsoft/extreme_feedback_device
|
207
|
+
licenses:
|
208
|
+
- MIT
|
209
|
+
metadata: {}
|
210
|
+
post_install_message:
|
211
|
+
rdoc_options: []
|
212
|
+
require_paths:
|
213
|
+
- lib
|
214
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
215
|
+
requirements:
|
216
|
+
- - '>='
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '0'
|
219
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
|
+
requirements:
|
221
|
+
- - '>='
|
222
|
+
- !ruby/object:Gem::Version
|
223
|
+
version: '0'
|
224
|
+
requirements: []
|
225
|
+
rubyforge_project:
|
226
|
+
rubygems_version: 2.0.3
|
227
|
+
signing_key:
|
228
|
+
specification_version: 4
|
229
|
+
summary: Fetches Jobs from a Jenkins CI via the REST JSON API and sets LEDs of an
|
230
|
+
Extreme Feedback Device to the status of the corresponding Job.
|
231
|
+
test_files:
|
232
|
+
- spec/extreme_feedback_device.yml
|
233
|
+
- spec/lib/extreme_feedback_device/cli_spec.rb
|
234
|
+
- spec/lib/extreme_feedback_device/jenkins_spec.rb
|
235
|
+
- spec/lib/extreme_feedback_device/job_spec.rb
|
236
|
+
- spec/lib/extreme_feedback_device_spec.rb
|
237
|
+
- spec/spec_helper.rb
|