shield-system 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +114 -0
- data/src/presets/github_build_status.rb +42 -0
- data/src/presets/helpers/build_status.rb +45 -0
- data/src/shield_system.rb +20 -0
- data/src/systems/github_shield.rb +109 -0
- data/src/systems/sparkline_shield.rb +52 -0
- metadata +100 -0
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# Generate Status Badge Images
|
2
|
+
|
3
|
+
Shield-System lets you generate github style status images for use anywhere e.g. custom badges with tests results.
|
4
|
+
|
5
|
+
[![Build Status](https://travis-ci.org/masterthought/thundercat.png?branch=master)](https://travis-ci.org/masterthought/thundercat)
|
6
|
+
|
7
|
+
## Background
|
8
|
+
|
9
|
+
I really like the travis,code climate and other services badges you can put on your github README and I wanted to make some I could use on
|
10
|
+
my internal projects and also be able to change the colours and text easily to make badges with different information for different sets of
|
11
|
+
tests and statuses.
|
12
|
+
|
13
|
+
## Install
|
14
|
+
|
15
|
+
gem install shield-system
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
### Create build status preset shields
|
20
|
+
|
21
|
+
![Passing]
|
22
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/passing.gif)
|
23
|
+
|
24
|
+
![Failing]
|
25
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/failing.gif)
|
26
|
+
|
27
|
+
![Pending]
|
28
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/pending.gif)
|
29
|
+
|
30
|
+
![Unstable]
|
31
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/unstable.gif)
|
32
|
+
|
33
|
+
![Error]
|
34
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/error.gif)
|
35
|
+
|
36
|
+
![Unknown]
|
37
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/unknown.gif)
|
38
|
+
|
39
|
+
require 'shield_system'
|
40
|
+
require 'shield_system/presets/github_build_status'
|
41
|
+
|
42
|
+
output_path = File.dirname(__FILE__)
|
43
|
+
build_status = GithubBuildStatus.new(output_path)
|
44
|
+
build_status.shield(BuildStatus.passing)
|
45
|
+
|
46
|
+
### Create custom shields
|
47
|
+
|
48
|
+
![Acceptance]
|
49
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/acceptance.gif)
|
50
|
+
|
51
|
+
![Functional]
|
52
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/functional.gif)
|
53
|
+
|
54
|
+
![EndtoEnd]
|
55
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/end-to-end.gif)
|
56
|
+
|
57
|
+
### using a custom shield
|
58
|
+
|
59
|
+
require 'shield_system'
|
60
|
+
|
61
|
+
output_path = File.dirname(__FILE__)
|
62
|
+
shield = ShieldSystem.new(output_path)
|
63
|
+
shield.github_shield('acceptance','Acceptance Tests',BuildStatus.passing.name,'#25B9E6',BuildStatus.passing.colour,'#0C0861','white')
|
64
|
+
shield.github_shield('functional','Functional Tests','108 Passing','#DCB9ED',BuildStatus.passing.colour,'#0C0861','white')
|
65
|
+
shield.github_shield('end-to-end','Number of End to End Tests:','500','#F08C4A','#F08C4A','#0C0861','#0C0861')
|
66
|
+
|
67
|
+
### changing height and font
|
68
|
+
|
69
|
+
![Height]
|
70
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/height.gif)
|
71
|
+
|
72
|
+
![Font]
|
73
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/font.gif)
|
74
|
+
|
75
|
+
shield.github_shield('height','Dependencies','up-to-date',BuildStatus.key.colour,BuildStatus.passing.colour,BuildStatus.value.colour,'white','none',30,15,'arial',50)
|
76
|
+
shield.github_shield('font','GPA','4.0','#25B9E6',BuildStatus.passing.colour,'#0C0861','white','none',20,13,'times')
|
77
|
+
|
78
|
+
### Creating Sparklines
|
79
|
+
|
80
|
+
![BarLabel]
|
81
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/build-history-label-bar.gif)
|
82
|
+
![Bar]
|
83
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/build-history-bar.gif)
|
84
|
+
|
85
|
+
![PieLabel]
|
86
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/build-history-label-pie.gif)
|
87
|
+
![Pie]
|
88
|
+
(https://raw.github.com/masterthought/shield-system/master/examples/images/build-history-pie.gif)
|
89
|
+
|
90
|
+
### sparklines bar and pie
|
91
|
+
|
92
|
+
# labels
|
93
|
+
shield.github_shield('build-history-label-bar','Build History','','#A8A7A5','#A8A7A5','white','white','none',28,13)
|
94
|
+
shield.github_shield('build-history-label-pie','Passing Tests','','#A8A7A5','#A8A7A5','white','white','none',28,13)
|
95
|
+
# sparklines
|
96
|
+
shield.sparkline_shield('build-history-bar',:bar,[100,100,90,80,90,90,100,120,120,90,80,70,100,120])
|
97
|
+
shield.sparkline_shield('build-history-pie',:pie,[70])
|
98
|
+
|
99
|
+
## Additional Info
|
100
|
+
|
101
|
+
github_shield takes several configuration parameters:
|
102
|
+
|
103
|
+
github_shield(shield_name, key_text, status_text, key_colour, status_colour, key_text_colour, status_text_colour, background_colour='none', height=18, font_size=11, font_family='arial', buffer=5)
|
104
|
+
|
105
|
+
most are self explanatory but here's some clarification on the last ones:
|
106
|
+
|
107
|
+
* background_colour = by default is 'none' but you can use this to set a specific colour
|
108
|
+
* buffer = by default is 5 - this is width added to the text width for the key and value you supply. The calculation for text width doesn't seem to take into account the font used so
|
109
|
+
when changing the font size the text doesn't line up correctly - you can increase the buffer to fix this if that happens.
|
110
|
+
|
111
|
+
## Develop
|
112
|
+
|
113
|
+
Interested in contributing? Great just let me know how you want to help.
|
114
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../shield_system'
|
2
|
+
require File.dirname(__FILE__) + '/../presets/helpers/build_status'
|
3
|
+
|
4
|
+
class GithubBuildStatus
|
5
|
+
|
6
|
+
def initialize(output_path,background_colour='none')
|
7
|
+
@shield = ShieldSystem.new(output_path)
|
8
|
+
@background_colour = background_colour
|
9
|
+
end
|
10
|
+
|
11
|
+
def passing
|
12
|
+
shield(BuildStatus.passing)
|
13
|
+
end
|
14
|
+
|
15
|
+
def failing
|
16
|
+
shield(BuildStatus.failing)
|
17
|
+
end
|
18
|
+
|
19
|
+
def pending
|
20
|
+
shield(BuildStatus.pending)
|
21
|
+
end
|
22
|
+
|
23
|
+
def unstable
|
24
|
+
shield(BuildStatus.unstable)
|
25
|
+
end
|
26
|
+
|
27
|
+
def error
|
28
|
+
shield(BuildStatus.error)
|
29
|
+
end
|
30
|
+
|
31
|
+
def unknown
|
32
|
+
shield(BuildStatus.unknown)
|
33
|
+
end
|
34
|
+
|
35
|
+
def shield(status, override_filename=false)
|
36
|
+
@shield.github_shield(override_filename ? status.name.downcase : BuildStatus.filename, BuildStatus.key.name, status.name,
|
37
|
+
BuildStatus.key.colour, status.colour, BuildStatus.value.colour, BuildStatus.value.colour, @background_colour)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
class BuildStatus
|
4
|
+
|
5
|
+
def self.passing
|
6
|
+
create('Passing','#3BB314')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.failing
|
10
|
+
create('Failing','#CC0000')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.pending
|
14
|
+
create('Pending','#E6B225')
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.unstable
|
18
|
+
create('Unstable','#D6C61A')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.error
|
22
|
+
create('Error','#A8A7A5')
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.unknown
|
26
|
+
create('Unknown','#A8A7A5')
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.key
|
30
|
+
create('Build','#575354')
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.value
|
34
|
+
create('value','white')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.filename
|
38
|
+
'build_status'
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.create(name,colour)
|
42
|
+
OpenStruct.new(:name => name,:colour => colour)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/systems/github_shield'
|
2
|
+
require File.dirname(__FILE__) + '/systems/sparkline_shield'
|
3
|
+
|
4
|
+
class ShieldSystem
|
5
|
+
|
6
|
+
def initialize(output_path)
|
7
|
+
@output_path = output_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def github_shield(shield_name, key_text, status_text, key_colour, status_colour, key_text_colour, status_text_colour, background_colour='none', height=18, font_size=11, font_family='arial', buffer=5)
|
11
|
+
GithubShield.new(shield_name, key_text, status_text, key_colour, status_colour, key_text_colour, status_text_colour, background_colour, @output_path, height, font_size, font_family, buffer).generate
|
12
|
+
end
|
13
|
+
|
14
|
+
def sparkline_shield(shield_name,chart_type,data,options={})
|
15
|
+
SparklineShield.new(shield_name,chart_type,data,options,@output_path).generate
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
|
3
|
+
class GithubShield
|
4
|
+
|
5
|
+
def initialize(shield_name, key_text, status_text, key_colour, status_colour, key_text_colour, status_text_colour, background_colour, output_path, height, font_size, font_family, buffer)
|
6
|
+
@shield_name = shield_name
|
7
|
+
@key_text = " #{key_text}"
|
8
|
+
@status_text = " #{status_text}"
|
9
|
+
@key_colour = key_colour
|
10
|
+
@status_colour = status_colour
|
11
|
+
@key_text_colour = key_text_colour
|
12
|
+
@status_text_colour = status_text_colour
|
13
|
+
$background_colour = background_colour
|
14
|
+
@output_path = output_path
|
15
|
+
@font_size = font_size.to_i
|
16
|
+
@font_family = font_family
|
17
|
+
@buffer = buffer.to_i
|
18
|
+
@key_width = get_text_width(@key_text)
|
19
|
+
@status_width = get_text_width(@status_text)
|
20
|
+
@width = @key_width + @status_width
|
21
|
+
@height = height.to_i
|
22
|
+
@canvas = Magick::Image.new(@width, @height){ self.background_color = $background_colour }
|
23
|
+
@canvas.alpha(Magick::ActivateAlphaChannel)
|
24
|
+
@draw = Magick::Draw.new
|
25
|
+
@corners = 3
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate
|
29
|
+
key_rectangle
|
30
|
+
status_rectangle
|
31
|
+
bridge_rectangle
|
32
|
+
key_text
|
33
|
+
status_text
|
34
|
+
publish
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def key_rectangle
|
40
|
+
@draw.fill(@key_colour)
|
41
|
+
@draw.stroke(@key_colour)
|
42
|
+
@draw.stroke_width(1)
|
43
|
+
@draw.roundrectangle(0, 0, @key_width, @height-1, @corners, @corners)
|
44
|
+
end
|
45
|
+
|
46
|
+
def status_rectangle
|
47
|
+
@draw.fill(@status_colour)
|
48
|
+
@draw.stroke('transparent')
|
49
|
+
@draw.stroke_width(1)
|
50
|
+
@draw.roundrectangle(@key_width, 0, @status_width+@key_width, @height-1, @corners, @corners)
|
51
|
+
end
|
52
|
+
|
53
|
+
def bridge_rectangle
|
54
|
+
@draw.fill(@key_colour)
|
55
|
+
@draw.stroke(@key_colour)
|
56
|
+
@draw.stroke_width(3)
|
57
|
+
@draw.rectangle(@key_width, 0, @key_width+1, @height-1)
|
58
|
+
@draw.stroke('transparent')
|
59
|
+
end
|
60
|
+
|
61
|
+
def key_text
|
62
|
+
@draw.fill(@key_text_colour)
|
63
|
+
@draw.font_family(@font_family)
|
64
|
+
@draw.font_size(@font_size)
|
65
|
+
@draw.text_antialias(true)
|
66
|
+
@draw.font_style(Magick::NormalStyle)
|
67
|
+
@draw.font_weight(Magick::BoldWeight)
|
68
|
+
@draw.gravity(Magick::WestGravity)
|
69
|
+
@draw.text(0, 0, @key_text)
|
70
|
+
end
|
71
|
+
|
72
|
+
def status_text
|
73
|
+
@draw.fill(@status_text_colour)
|
74
|
+
@draw.font_family(@font_family)
|
75
|
+
@draw.font_size(@font_size)
|
76
|
+
@draw.text_antialias(true)
|
77
|
+
@draw.font_style(Magick::NormalStyle)
|
78
|
+
@draw.font_weight(Magick::BoldWeight)
|
79
|
+
@draw.gravity(Magick::WestGravity)
|
80
|
+
@draw.text(@key_width, 0, @status_text)
|
81
|
+
end
|
82
|
+
|
83
|
+
def publish
|
84
|
+
@draw.draw(@canvas)
|
85
|
+
@canvas.write(@output_path + '/' + @shield_name + '.gif')
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_text_width(text)
|
89
|
+
canvas = Magick::Image.new(100, 100){ self.background_color = 'transparent' }
|
90
|
+
canvas.alpha(Magick::ActivateAlphaChannel)
|
91
|
+
label = Magick::Draw.new
|
92
|
+
label.font_family(@font_family)
|
93
|
+
label.font_size(@font_size)
|
94
|
+
label.text_antialias(true)
|
95
|
+
label.font_style(Magick::NormalStyle)
|
96
|
+
label.font_weight(Magick::BoldWeight)
|
97
|
+
label.gravity(Magick::WestGravity)
|
98
|
+
label.text(0, 0, text)
|
99
|
+
metrics = label.get_type_metrics(canvas, text)
|
100
|
+
metrics.width.to_i + @buffer
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'sparklines'
|
2
|
+
require 'RMagick'
|
3
|
+
|
4
|
+
class SparklineShield
|
5
|
+
|
6
|
+
def initialize(shield_name, chart_type, data, options, output_path)
|
7
|
+
@shield_name = shield_name
|
8
|
+
@chart_type = chart_type.to_sym
|
9
|
+
@data = data
|
10
|
+
@options = options
|
11
|
+
@output_path = output_path
|
12
|
+
@shield_list = [:bar,:pie]
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate
|
16
|
+
raise ArgumentError, "Chart type: #{@chart_type} not supported - please use one of: #{@shield_list}" unless @shield_list.include?(@chart_type)
|
17
|
+
send @chart_type
|
18
|
+
end
|
19
|
+
|
20
|
+
def bar
|
21
|
+
Sparklines.plot_to_file(@output_path + "/#{@shield_name}.gif",
|
22
|
+
@data, bar_default_options.merge(@options))
|
23
|
+
end
|
24
|
+
|
25
|
+
def bar_default_options
|
26
|
+
{
|
27
|
+
:type => 'bar',
|
28
|
+
:below_color => 'blue',
|
29
|
+
:above_color => 'orange',
|
30
|
+
:upper => 0,
|
31
|
+
:step => 6,
|
32
|
+
:height => 30,
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def pie
|
37
|
+
Sparklines.plot_to_file(@output_path + "/#{@shield_name}.gif",
|
38
|
+
@data,
|
39
|
+
pie_default_options.merge(@options))
|
40
|
+
end
|
41
|
+
|
42
|
+
def pie_default_options
|
43
|
+
{
|
44
|
+
:type => 'pie',
|
45
|
+
:share_color => '#3BB314',
|
46
|
+
:remain_color => '#C8EDFA',
|
47
|
+
:diameter => 30
|
48
|
+
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shield-system
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kingsley Hendrickse
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rmagick
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
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
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sparklines
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Create status badge images for use on github pages etc
|
63
|
+
email: kingsley@masterthought.net
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files:
|
67
|
+
- README.md
|
68
|
+
files:
|
69
|
+
- src/shield_system.rb
|
70
|
+
- src/systems/github_shield.rb
|
71
|
+
- src/systems/sparkline_shield.rb
|
72
|
+
- src/presets/helpers/build_status.rb
|
73
|
+
- src/presets/github_build_status.rb
|
74
|
+
- README.md
|
75
|
+
homepage: https://github.com/masterthought/shield-system
|
76
|
+
licenses:
|
77
|
+
- Apache 2.0
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- src
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.8.25
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: Create status badge images for use on github pages etc
|
100
|
+
test_files: []
|