shield-system 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.
- 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
|
+
[](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: []
|