hipchat-chef 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.textile +98 -0
- data/Rakefile +19 -0
- data/hipchat-chef.gemspec +31 -0
- data/lib/hipchat-chef.rb +188 -0
- data/lib/hipchat-chef/capistrano.rb +131 -0
- data/lib/hipchat-chef/chef.rb +55 -0
- data/lib/hipchat-chef/rails3_tasks.rb +44 -0
- data/lib/hipchat-chef/railtie.rb +9 -0
- data/lib/hipchat-chef/version.rb +3 -0
- data/spec/example/history.json +36 -0
- data/spec/hipchat_spec.rb +209 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZDQwMGJiNGJkYzFmMTA3YTIxY2NlYmNhNzUzZDBiOTRmYWEzN2FkZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZGQxNmUwM2Q3NTAyOWNlYzg1MWE3ZmE4MjI4NWQ0ZjdkYzdmOTcyMg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YmRkMjg2YWIyM2JkZWU0OWE3NDMxYjM1YmJiMWI5Y2EzMDdhZjc0MGE5ZDc1
|
10
|
+
ZDEyZjUzYTExOTk0ODJjMWNjMTZkZDAxZGVkNDYwNGVmZTMxYjA2NWE1ZTBj
|
11
|
+
ZTQ4NjdmOTk4MzgwNjBlZmJhYjI3MzMzNjAzZGEwMjBjYmQxYTA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDFmY2M1N2I1MzY1ZTJjMDdkZmRmODY5OGIwZDhhMDE1ODI4OTE0NzE0NjY2
|
14
|
+
NmZmMzJmMTExMTZjZWIwN2YzNDJhODdiMmE2ZThmNGFjMmMyZTI2NTlmMjc2
|
15
|
+
YzBiNTM4ZWRlYWMzZjYzOTgyZGRkYWQyY2Q3ZDJkMmZmOGM2NDg=
|
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
coverage
|
18
|
+
rdoc
|
19
|
+
pkg
|
20
|
+
*.gem
|
21
|
+
*.rbc
|
22
|
+
.bundle
|
23
|
+
.config
|
24
|
+
.yardoc
|
25
|
+
/Gemfile.lock
|
26
|
+
InstalledFiles
|
27
|
+
_yardoc
|
28
|
+
doc/
|
29
|
+
lib/bundler/man
|
30
|
+
spec/reports
|
31
|
+
test/tmp
|
32
|
+
test/version_tmp
|
33
|
+
tmp
|
34
|
+
|
35
|
+
## PROJECT::SPECIFIC
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Atlassian
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
h1. HipChat Wrapper
|
2
|
+
|
3
|
+
A very basic wrapper for the HipChat HTTP API.
|
4
|
+
|
5
|
+
h2. Build Status
|
6
|
+
|
7
|
+
"!https://travis-ci.org/hipchat/hipchat-rb.png!":https://travis-ci.org/hipchat/hipchat-rb
|
8
|
+
|
9
|
+
h2. Requirements
|
10
|
+
* Ruby 1.9.3 or higher
|
11
|
+
* HipChat Account, sign up "here!":https://hipchat.com/
|
12
|
+
|
13
|
+
h2. Usage
|
14
|
+
|
15
|
+
bc.. client = HipChat::Client.new(api_token)
|
16
|
+
# 'username' is the name for which the message will be presented as from
|
17
|
+
client['my room'].send('username', 'I talk')
|
18
|
+
|
19
|
+
# Send notifications to users (default false)
|
20
|
+
client['my room'].send('username', 'I quit!', :notify => true)
|
21
|
+
|
22
|
+
# Color it red. or "yellow", "green", "purple", "random" (default "yellow")
|
23
|
+
client['my room'].send('username', 'Build failed!', :color => 'red')
|
24
|
+
|
25
|
+
# Have your message rendered as text in HipChat (see https://www.hipchat.com/docs/api/method/rooms/message)
|
26
|
+
client['my room'].send('username', '@coworker Build faild!', :message_format => 'text')
|
27
|
+
|
28
|
+
# Update the topic of a room in HipChat (see https://www.hipchat.com/docs/api/method/rooms/topic)
|
29
|
+
client['my room'].topic('Free Ice Cream in the kitchen')
|
30
|
+
|
31
|
+
# Change the from field for a topic update (default "API")
|
32
|
+
client['my room'].topic('Weekely sales: $10,000', :from => 'Sales Team')
|
33
|
+
|
34
|
+
# Get history from a room
|
35
|
+
client['my room'].history()
|
36
|
+
|
37
|
+
# Get history for a date in time with a particular timezone (default is latest 75 messages, timezone default is 'UTC')
|
38
|
+
client['my room'].history(:date => '2010-11-19', :timezone => 'PST')
|
39
|
+
|
40
|
+
|
41
|
+
h2. Capistrano
|
42
|
+
|
43
|
+
bc.. require 'hipchat/capistrano'
|
44
|
+
|
45
|
+
set :hipchat_token, "<your token>"
|
46
|
+
set :hipchat_room_name, "Your room" # If you pass an array such as ["room_a", "room_b"] you can send announcements to multiple rooms.
|
47
|
+
set :hipchat_announce, false # notify users
|
48
|
+
set :hipchat_color, 'yellow' #normal message color
|
49
|
+
set :hipchat_success_color, 'green' #finished deployment message color
|
50
|
+
set :hipchat_failed_color, 'red' #cancelled deployment message color
|
51
|
+
set :hipchat_message_format, 'text' # Sets the deployment message format, see https://www.hipchat.com/docs/api/method/rooms/message
|
52
|
+
|
53
|
+
h3. Who did it?
|
54
|
+
|
55
|
+
To determine the user that is currently running the deploy, the capistrano tasks will look for the following:
|
56
|
+
|
57
|
+
# The $HIPCHAT_USER environment variable
|
58
|
+
# The hipchat_human capistrano var.
|
59
|
+
# The git user.name var.
|
60
|
+
# The $USER environment variable.
|
61
|
+
|
62
|
+
h2. Rails 3 Rake Task
|
63
|
+
|
64
|
+
Send a message using a rake task:
|
65
|
+
|
66
|
+
bc. rake hipchat:send["hello world"]
|
67
|
+
|
68
|
+
or
|
69
|
+
|
70
|
+
bc. rake hipchat:send MESSAGE="hello world"
|
71
|
+
|
72
|
+
Options like the room, API token, user name and notification flag can be set in YAML.
|
73
|
+
|
74
|
+
RAILS_ROOT/config/hipchat.yml:
|
75
|
+
|
76
|
+
bc.. token: "<your token>"
|
77
|
+
room: "Your room"
|
78
|
+
user: "Your name" # Default to `whoami`
|
79
|
+
notify: true # Defaults to false
|
80
|
+
|
81
|
+
h2. Engine Yard
|
82
|
+
|
83
|
+
Use a "deploy hook":http://bit.ly/qnbIkP to send messages from Engine Yard's Cloud platform.
|
84
|
+
|
85
|
+
RAILS_ROOT/deploy/after_restart.rb:
|
86
|
+
|
87
|
+
bc.. on_app_master do
|
88
|
+
message = "Deploying revision #{revision[0...6]} to #{node[:environment][:name]}"
|
89
|
+
message += " (with migrations)" if migrate?
|
90
|
+
message += "."
|
91
|
+
|
92
|
+
# Send a message via rake task assuming a hipchat.yml in your config like above
|
93
|
+
run "cd #{release_path} && bundle exec rake hipchat:send MESSAGE='#{message}'"
|
94
|
+
end
|
95
|
+
|
96
|
+
h2. Copyright
|
97
|
+
|
98
|
+
Copyright (c) 2012 Atlassian. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new do |t|
|
5
|
+
t.pattern = 'spec/**/*_spec.rb'
|
6
|
+
t.rspec_opts = '-c -fd'
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default => :spec
|
10
|
+
|
11
|
+
require 'rdoc/task'
|
12
|
+
Rake::RDocTask.new do |rdoc|
|
13
|
+
version = HipChat::VERSION
|
14
|
+
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = "hipchat #{version}"
|
17
|
+
rdoc.rdoc_files.include('README*')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hipchat-chef/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hipchat-chef"
|
8
|
+
spec.version = HipChat::VERSION
|
9
|
+
spec.authors = ["HipChat/Atlassian"]
|
10
|
+
spec.email = ["support@hipchat.com"]
|
11
|
+
spec.description = %q{Ruby library to interact with HipChat}
|
12
|
+
spec.summary = %q{Ruby library to interact with HipChat}
|
13
|
+
spec.homepage = "https://github.com/hipchat/hipchat-rb"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 1.9.3'
|
22
|
+
|
23
|
+
spec.add_dependency "httparty"
|
24
|
+
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "rr"
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "webmock"
|
30
|
+
spec.add_development_dependency 'rdoc', '> 2.4.2'
|
31
|
+
end
|
data/lib/hipchat-chef.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
require 'hipchat-chef/railtie' if defined?(Rails::Railtie)
|
5
|
+
require "hipchat-chef/version"
|
6
|
+
|
7
|
+
module HipChat
|
8
|
+
class UnknownRoom < StandardError; end
|
9
|
+
class Unauthorized < StandardError; end
|
10
|
+
class UnknownResponseCode < StandardError; end
|
11
|
+
class UsernameTooLong < StandardError; end
|
12
|
+
|
13
|
+
class Client
|
14
|
+
include HTTParty
|
15
|
+
|
16
|
+
base_uri 'https://api.hipchat.com/v1/rooms'
|
17
|
+
format :json
|
18
|
+
|
19
|
+
def initialize(token, options={})
|
20
|
+
@token = token
|
21
|
+
|
22
|
+
http_proxy = options[:http_proxy] || ENV['http_proxy']
|
23
|
+
setup_proxy(http_proxy) if http_proxy
|
24
|
+
end
|
25
|
+
|
26
|
+
def rooms
|
27
|
+
@rooms ||= self.class.get("/list", :query => {:auth_token => @token})['rooms'].
|
28
|
+
map { |r| Room.new(@token, r) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](name)
|
32
|
+
Room.new(@token, :room_id => name)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def setup_proxy(proxy_url)
|
37
|
+
proxy_url = URI.parse(proxy_url)
|
38
|
+
|
39
|
+
self.class.http_proxy(proxy_url.host, proxy_url.port,
|
40
|
+
proxy_url.user, proxy_url.password)
|
41
|
+
HipChat::Room.http_proxy(proxy_url.host, proxy_url.port,
|
42
|
+
proxy_url.user, proxy_url.password)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Room < OpenStruct
|
47
|
+
include HTTParty
|
48
|
+
|
49
|
+
base_uri 'https://api.hipchat.com/v1/rooms'
|
50
|
+
|
51
|
+
def initialize(token, params)
|
52
|
+
@token = token
|
53
|
+
|
54
|
+
super(params)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Send a message to this room.
|
58
|
+
#
|
59
|
+
# Usage:
|
60
|
+
#
|
61
|
+
# # Default
|
62
|
+
# send 'nickname', 'some message'
|
63
|
+
#
|
64
|
+
# # Notify users and color the message red
|
65
|
+
# send 'nickname', 'some message', :notify => true, :color => 'red'
|
66
|
+
#
|
67
|
+
# # Notify users (deprecated)
|
68
|
+
# send 'nickname', 'some message', true
|
69
|
+
#
|
70
|
+
# Options:
|
71
|
+
#
|
72
|
+
# +color+:: "yellow", "red", "green", "purple", or "random"
|
73
|
+
# (default "yellow")
|
74
|
+
# +notify+:: true or false
|
75
|
+
# (default false)
|
76
|
+
def send(from, message, options_or_notify = {})
|
77
|
+
if from.length > 15
|
78
|
+
raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 15'"
|
79
|
+
end
|
80
|
+
options = if options_or_notify == true or options_or_notify == false
|
81
|
+
warn "DEPRECATED: Specify notify flag as an option (e.g., :notify => true)"
|
82
|
+
{ :notify => options_or_notify }
|
83
|
+
else
|
84
|
+
options_or_notify || {}
|
85
|
+
end
|
86
|
+
|
87
|
+
options = { :color => 'yellow', :notify => false }.merge options
|
88
|
+
|
89
|
+
response = self.class.post('/message',
|
90
|
+
:query => { :auth_token => @token },
|
91
|
+
:body => {
|
92
|
+
:room_id => room_id,
|
93
|
+
:from => from,
|
94
|
+
:message => message,
|
95
|
+
:message_format => options[:message_format] || 'html',
|
96
|
+
:color => options[:color],
|
97
|
+
:notify => options[:notify] ? 1 : 0
|
98
|
+
}
|
99
|
+
)
|
100
|
+
|
101
|
+
case response.code
|
102
|
+
when 200; true
|
103
|
+
when 404
|
104
|
+
raise UnknownRoom, "Unknown room: `#{room_id}'"
|
105
|
+
when 401
|
106
|
+
raise Unauthorized, "Access denied to room `#{room_id}'"
|
107
|
+
else
|
108
|
+
raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Change this room's topic
|
113
|
+
#
|
114
|
+
# Usage:
|
115
|
+
#
|
116
|
+
# # Default
|
117
|
+
# topic 'my awesome topic'
|
118
|
+
#
|
119
|
+
# Options:
|
120
|
+
#
|
121
|
+
# +from+:: the name of the person changing the topic
|
122
|
+
# (default "API")
|
123
|
+
def topic(new_topic, options = {})
|
124
|
+
|
125
|
+
options = { :from => 'API' }.merge options
|
126
|
+
|
127
|
+
response = self.class.post('/topic',
|
128
|
+
:query => { :auth_token => @token },
|
129
|
+
:body => {
|
130
|
+
:room_id => room_id,
|
131
|
+
:from => options[:from],
|
132
|
+
:topic => new_topic
|
133
|
+
}
|
134
|
+
)
|
135
|
+
|
136
|
+
case response.code
|
137
|
+
when 200; true
|
138
|
+
when 404
|
139
|
+
raise UnknownRoom, "Unknown room: `#{room_id}'"
|
140
|
+
when 401
|
141
|
+
raise Unauthorized, "Access denied to room `#{room_id}'"
|
142
|
+
else
|
143
|
+
raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Pull this room's history
|
148
|
+
#
|
149
|
+
# Usage
|
150
|
+
#
|
151
|
+
# # Default
|
152
|
+
#
|
153
|
+
#
|
154
|
+
# Options
|
155
|
+
#
|
156
|
+
# +date+:: Whether to return a specific day (YYYY-MM-DD format) or recent
|
157
|
+
# (default "recent")
|
158
|
+
# +timezone+:: Your timezone. Supported timezones are at: https://www.hipchat.com/docs/api/timezones
|
159
|
+
# (default "UTC")
|
160
|
+
# +format+:: Format to retrieve the history in. Valid options are JSON and XML
|
161
|
+
# (default "JSON")
|
162
|
+
def history(options = {})
|
163
|
+
|
164
|
+
options = { :date => 'recent', :timezone => 'UTC', :format => 'JSON' }.merge options
|
165
|
+
|
166
|
+
response = self.class.get('/history',
|
167
|
+
:query => {
|
168
|
+
:room_id => room_id,
|
169
|
+
:date => options[:date],
|
170
|
+
:timezone => options[:timezone],
|
171
|
+
:format => options[:format],
|
172
|
+
:auth_token => @token,
|
173
|
+
}
|
174
|
+
)
|
175
|
+
|
176
|
+
case response.code
|
177
|
+
when 200
|
178
|
+
response.body
|
179
|
+
when 404
|
180
|
+
raise UnknownRoom, "Unknown room: `#{room_id}'"
|
181
|
+
when 401
|
182
|
+
raise Unauthorized, "Access denied to room `#{room_id}'"
|
183
|
+
else
|
184
|
+
raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'hipchat-chef'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
set :hipchat_send_notification, false
|
5
|
+
set :hipchat_with_migrations, ''
|
6
|
+
|
7
|
+
namespace :hipchat do
|
8
|
+
task :trigger_notification do
|
9
|
+
set :hipchat_send_notification, true if !dry_run
|
10
|
+
end
|
11
|
+
|
12
|
+
task :configure_for_migrations do
|
13
|
+
set :hipchat_with_migrations, ' (with migrations)'
|
14
|
+
end
|
15
|
+
|
16
|
+
task :notify_deploy_started do
|
17
|
+
if hipchat_send_notification
|
18
|
+
|
19
|
+
environment_string = env
|
20
|
+
if self.respond_to?(:stage)
|
21
|
+
environment_string = "#{stage} (#{env})"
|
22
|
+
end
|
23
|
+
|
24
|
+
on_rollback do
|
25
|
+
send_options.merge!(:color => failed_message_color)
|
26
|
+
send("#{human} cancelled deployment of #{deployment_name} to #{environment_string}.", send_options)
|
27
|
+
end
|
28
|
+
|
29
|
+
send("#{human} is deploying #{deployment_name} to #{environment_string}#{fetch(:hipchat_with_migrations, '')}.", send_options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task :notify_deploy_finished do
|
34
|
+
if hipchat_send_notification
|
35
|
+
send_options.merge!(:color => success_message_color)
|
36
|
+
|
37
|
+
environment_string = env
|
38
|
+
if self.respond_to?(:stage)
|
39
|
+
environment_string = "#{stage} (#{env})"
|
40
|
+
end
|
41
|
+
|
42
|
+
send("#{human} finished deploying #{deployment_name} to #{environment_string}#{fetch(:hipchat_with_migrations, '')}.", send_options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_options
|
47
|
+
return @send_options if defined?(@send_options)
|
48
|
+
@send_options = message_format ? {:message_format => message_format } : {}
|
49
|
+
@send_options.merge!(:notify => message_notification)
|
50
|
+
@send_options.merge!(:color => message_color)
|
51
|
+
@send_options
|
52
|
+
end
|
53
|
+
|
54
|
+
def send(message, options)
|
55
|
+
set :hipchat_client, HipChat::Client.new(hipchat_token) if fetch(:hipchat_client, nil).nil?
|
56
|
+
|
57
|
+
if hipchat_room_name.is_a?(String)
|
58
|
+
rooms = [hipchat_room_name]
|
59
|
+
elsif hipchat_room_name.is_a?(Symbol)
|
60
|
+
rooms = [hipchat_room_name.to_s]
|
61
|
+
else
|
62
|
+
rooms = hipchat_room_name
|
63
|
+
end
|
64
|
+
|
65
|
+
rooms.each { |room|
|
66
|
+
begin
|
67
|
+
hipchat_client[room].send(deploy_user, message, options)
|
68
|
+
rescue => e
|
69
|
+
puts e.message
|
70
|
+
puts e.backtrace
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def deployment_name
|
76
|
+
if fetch(:branch, nil)
|
77
|
+
name = "#{application}/#{branch}"
|
78
|
+
name += " (revision #{real_revision[0..7]})" if real_revision
|
79
|
+
name
|
80
|
+
else
|
81
|
+
application
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def message_color
|
86
|
+
fetch(:hipchat_color, nil)
|
87
|
+
end
|
88
|
+
|
89
|
+
def success_message_color
|
90
|
+
fetch(:hipchat_success_color, "green")
|
91
|
+
end
|
92
|
+
|
93
|
+
def failed_message_color
|
94
|
+
fetch(:hipchat_failed_color, "red")
|
95
|
+
end
|
96
|
+
|
97
|
+
def message_notification
|
98
|
+
fetch(:hipchat_announce, false)
|
99
|
+
end
|
100
|
+
|
101
|
+
def message_format
|
102
|
+
fetch(:hipchat_message_format, "html")
|
103
|
+
end
|
104
|
+
|
105
|
+
def deploy_user
|
106
|
+
fetch(:hipchat_deploy_user, "Deploy")
|
107
|
+
end
|
108
|
+
|
109
|
+
def human
|
110
|
+
ENV['HIPCHAT_USER'] ||
|
111
|
+
fetch(:hipchat_human,
|
112
|
+
if (u = %x{git config user.name}.strip) != ""
|
113
|
+
u
|
114
|
+
elsif (u = ENV['USER']) != ""
|
115
|
+
u
|
116
|
+
else
|
117
|
+
"Someone"
|
118
|
+
end)
|
119
|
+
end
|
120
|
+
|
121
|
+
def env
|
122
|
+
fetch(:hipchat_env, fetch(:rack_env, fetch(:rails_env, "production")))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
before "deploy", "hipchat:trigger_notification"
|
127
|
+
before "deploy:migrations", "hipchat:trigger_notification", "hipchat:configure_for_migrations"
|
128
|
+
before "deploy:update_code", "hipchat:notify_deploy_started"
|
129
|
+
after "deploy", "hipchat:notify_deploy_finished"
|
130
|
+
after "deploy:migrations", "hipchat:notify_deploy_finished"
|
131
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'hipchat-chef'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Provides a Chef exception handler so you can send information about
|
5
|
+
# chef-client failures to a HipChat room.
|
6
|
+
#
|
7
|
+
# Docs: http://wiki.opscode.com/display/chef/Exception+and+Report+Handlers
|
8
|
+
#
|
9
|
+
# Install - add the following to your client.rb:
|
10
|
+
# require 'hipchat/chef'
|
11
|
+
# hipchat_handler = HipChat::NotifyRoom.new("<api token>", "<room name>")
|
12
|
+
# exception_handlers << hipchat_handler
|
13
|
+
#
|
14
|
+
|
15
|
+
module HipChat
|
16
|
+
class NotifyRoom < Chef::Handler
|
17
|
+
|
18
|
+
def initialize(api_token, room_name, notify_users=false, report_success=false, excluded_envs=[], override_colors={})
|
19
|
+
@api_token = api_token
|
20
|
+
@room_name = room_name
|
21
|
+
@notify_users = notify_users
|
22
|
+
@report_success = report_success
|
23
|
+
@excluded_envs = excluded_envs
|
24
|
+
@override_colors = override_colors
|
25
|
+
end
|
26
|
+
|
27
|
+
def report
|
28
|
+
unless @excluded_envs.include?(node.chef_environment)
|
29
|
+
msg = if run_status.failed? then "Failure on \"<b>#{node.name}</b>\" (<b>#{node.chef_environment}</b>, <b>#{node['ipaddress']}</b>):\n#{run_status.formatted_exception}"
|
30
|
+
elsif run_status.success? && @report_success
|
31
|
+
"Chef run on \"#{node.name}\" completed in #{run_status.elapsed_time.round(2)} seconds"
|
32
|
+
else nil
|
33
|
+
end
|
34
|
+
|
35
|
+
@override_colors.default_proc = proc do |h, k|
|
36
|
+
case k
|
37
|
+
when String then sym = k.to_sym; h[sym] if h.key?(sym)
|
38
|
+
when Symbol then str = k.to_s; h[str] if h.key?(str)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
color = if run_status.success?
|
43
|
+
@override_colors[:success].to_s || 'green'
|
44
|
+
else
|
45
|
+
@override_colors[:failure].to_s || 'red'
|
46
|
+
end
|
47
|
+
|
48
|
+
if msg
|
49
|
+
client = HipChat::Client.new(@api_token)
|
50
|
+
client[@room_name].send('Chef', msg, :notify => @notify_users, :color => color)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'hipchat-chef'
|
2
|
+
|
3
|
+
namespace :hipchat do
|
4
|
+
desc "Sends a HipChat message as a particular user"
|
5
|
+
task :send, [:message] do |t, args|
|
6
|
+
required_options = [:message, :room, :token, :user]
|
7
|
+
config_file = Rails.root.join 'config', 'hipchat.yml'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
:message => ENV['MESSAGE'],
|
11
|
+
:message_format => ENV['MESSAGE_FORMAT'],
|
12
|
+
:user => ENV['HIPCHAT_USER'],
|
13
|
+
:notify => ENV['NOTIFY'],
|
14
|
+
:room => ENV['ROOM'],
|
15
|
+
:token => ENV['TOKEN']
|
16
|
+
}.reject { |k, v| v.blank? }
|
17
|
+
|
18
|
+
system_options = {
|
19
|
+
:user => ENV['USER']
|
20
|
+
}.reject { |k, v| v.blank? }
|
21
|
+
|
22
|
+
argument_options = {
|
23
|
+
:message => args.message
|
24
|
+
}.reject { |k, v| v.blank? }
|
25
|
+
|
26
|
+
if File.exists? config_file
|
27
|
+
options.reverse_merge! YAML.load_file(config_file).symbolize_keys
|
28
|
+
end
|
29
|
+
|
30
|
+
options.reverse_merge! system_options
|
31
|
+
options.merge! argument_options
|
32
|
+
|
33
|
+
options[:notify] = options[:notify].to_s != 'false'
|
34
|
+
|
35
|
+
if (missing_options = required_options - options.keys).size > 0
|
36
|
+
puts "HipChat needs #{missing_options.to_sentence} to send!"
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
client = HipChat::Client.new(options[:token])
|
41
|
+
|
42
|
+
client[options[:room]].send(options[:user], options[:message], :notify => options[:notify])
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Content-Type: application/json
|
3
|
+
|
4
|
+
{
|
5
|
+
"messages": [
|
6
|
+
{
|
7
|
+
"date": "2010-11-19T15:48:19-0800",
|
8
|
+
"from": {
|
9
|
+
"name": "Garret Heaton",
|
10
|
+
"user_id": 10
|
11
|
+
},
|
12
|
+
"message": "Good morning! This is a regular message."
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"date": "2010-11-19T15:49:44-0800",
|
16
|
+
"from": {
|
17
|
+
"name": "Garret Heaton",
|
18
|
+
"user_id": 10
|
19
|
+
},
|
20
|
+
"file": {
|
21
|
+
"name": "Screenshot.png",
|
22
|
+
"size": 141909,
|
23
|
+
"url": "http:\/\/uploads.hipchat.com\/xxx\/Screenshot.png"
|
24
|
+
},
|
25
|
+
"message": "This is a file upload"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"date": "2010-11-19T16:13:40-0800",
|
29
|
+
"from": {
|
30
|
+
"name": "Deploy Bot",
|
31
|
+
"user_id": "api"
|
32
|
+
},
|
33
|
+
"message": "This message is sent via the API so the user_id is 'api'."
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe HipChat do
|
4
|
+
subject { HipChat::Client.new("blah") }
|
5
|
+
|
6
|
+
let(:room) { subject["Hipchat"] }
|
7
|
+
|
8
|
+
# Helper for mocking room message post requests
|
9
|
+
def mock_successful_send(from, message, options={})
|
10
|
+
options = {:color => 'yellow', :notify => 0, :message_format => 'html'}.merge(options)
|
11
|
+
mock(HipChat::Room).post("/message",
|
12
|
+
:query => {:auth_token => "blah"},
|
13
|
+
:body => {:room_id => "Hipchat",
|
14
|
+
:from => "Dude",
|
15
|
+
:message => "Hello world",
|
16
|
+
:message_format => options[:message_format],
|
17
|
+
:color => options[:color],
|
18
|
+
:notify => options[:notify]}) {
|
19
|
+
OpenStruct.new(:code => 200)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def mock_successful_topic_change(topic, options={})
|
24
|
+
options = {:from => 'API'}.merge(options)
|
25
|
+
mock(HipChat::Room).post("/topic",
|
26
|
+
:query => {:auth_token => "blah"},
|
27
|
+
:body => {:room_id => "Hipchat",
|
28
|
+
:from => options[:from],
|
29
|
+
:topic => "Nice topic" } ) {
|
30
|
+
OpenStruct.new(:code => 200)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def mock_successful_history(options={})
|
35
|
+
options = { :date => 'recent', :timezone => 'UTC', :format => 'JSON' }.merge(options)
|
36
|
+
canned_response = File.new File.expand_path(File.dirname(__FILE__) + '/example/history.json')
|
37
|
+
stub_request(:get, "https://api.hipchat.com/v1/rooms/history").with(:query => {:auth_token => "blah",
|
38
|
+
:room_id => "Hipchat",
|
39
|
+
:date => options[:date],
|
40
|
+
:timezone => options[:timezone],
|
41
|
+
:format => options[:format]}).to_return(canned_response)
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#history" do
|
45
|
+
it "is successful without custom options" do
|
46
|
+
mock_successful_history()
|
47
|
+
|
48
|
+
room.history().should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "is successful with custom options" do
|
52
|
+
mock_successful_history(:timezone => 'America/Los_Angeles', :date => '2010-11-19')
|
53
|
+
room.history(:timezone => 'America/Los_Angeles', :date => '2010-11-19').should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "fails when the room doen't exist" do
|
57
|
+
mock(HipChat::Room).get(anything, anything) {
|
58
|
+
OpenStruct.new(:code => 404)
|
59
|
+
}
|
60
|
+
|
61
|
+
lambda { room.history }.should raise_error(HipChat::UnknownRoom)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "fails when we're not allowed to do so" do
|
65
|
+
mock(HipChat::Room).get(anything, anything) {
|
66
|
+
OpenStruct.new(:code => 401)
|
67
|
+
}
|
68
|
+
|
69
|
+
lambda { room.history }.should raise_error(HipChat::Unauthorized)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "fails if we get an unknown response code" do
|
73
|
+
mock(HipChat::Room).get(anything, anything) {
|
74
|
+
OpenStruct.new(:code => 403)
|
75
|
+
}
|
76
|
+
|
77
|
+
lambda { room.history }.
|
78
|
+
should raise_error(HipChat::UnknownResponseCode)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#topic" do
|
83
|
+
it "is successful without custom options" do
|
84
|
+
mock_successful_topic_change("Nice topic")
|
85
|
+
|
86
|
+
room.topic("Nice topic").should be_true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "is successful with a custom from" do
|
90
|
+
mock_successful_topic_change("Nice topic", :from => "Me")
|
91
|
+
|
92
|
+
room.topic("Nice topic", :from => "Me").should be_true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "fails when the room doesn't exist" do
|
96
|
+
mock(HipChat::Room).post(anything, anything) {
|
97
|
+
OpenStruct.new(:code => 404)
|
98
|
+
}
|
99
|
+
|
100
|
+
lambda { room.topic "" }.should raise_error(HipChat::UnknownRoom)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "fails when we're not allowed to do so" do
|
104
|
+
mock(HipChat::Room).post(anything, anything) {
|
105
|
+
OpenStruct.new(:code => 401)
|
106
|
+
}
|
107
|
+
|
108
|
+
lambda { room.topic "" }.should raise_error(HipChat::Unauthorized)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "fails if we get an unknown response code" do
|
112
|
+
mock(HipChat::Room).post(anything, anything) {
|
113
|
+
OpenStruct.new(:code => 403)
|
114
|
+
}
|
115
|
+
|
116
|
+
lambda { room.topic "" }.
|
117
|
+
should raise_error(HipChat::UnknownResponseCode)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "sends a message to a room" do
|
122
|
+
it "successfully without custom options" do
|
123
|
+
mock_successful_send 'Dude', 'Hello world'
|
124
|
+
|
125
|
+
room.send("Dude", "Hello world").should be_true
|
126
|
+
end
|
127
|
+
|
128
|
+
it "successfully with notifications on as option" do
|
129
|
+
mock_successful_send 'Dude', 'Hello world', :notify => 1
|
130
|
+
|
131
|
+
room.send("Dude", "Hello world", :notify => true).should be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it "successfully with custom color" do
|
135
|
+
mock_successful_send 'Dude', 'Hello world', :color => 'red'
|
136
|
+
|
137
|
+
room.send("Dude", "Hello world", :color => 'red').should be_true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "successfully with text message_format" do
|
141
|
+
mock_successful_send 'Dude', 'Hello world', :message_format => 'text'
|
142
|
+
|
143
|
+
room.send("Dude", "Hello world", :message_format => 'text').should be_true
|
144
|
+
end
|
145
|
+
|
146
|
+
it "but fails when the room doesn't exist" do
|
147
|
+
mock(HipChat::Room).post(anything, anything) {
|
148
|
+
OpenStruct.new(:code => 404)
|
149
|
+
}
|
150
|
+
|
151
|
+
lambda { room.send "", "" }.should raise_error(HipChat::UnknownRoom)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "but fails when we're not allowed to do so" do
|
155
|
+
mock(HipChat::Room).post(anything, anything) {
|
156
|
+
OpenStruct.new(:code => 401)
|
157
|
+
}
|
158
|
+
|
159
|
+
lambda { room.send "", "" }.should raise_error(HipChat::Unauthorized)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "but fails if the username is more than 15 chars" do
|
163
|
+
lambda { room.send "a very long username here", "a message" }.should raise_error(HipChat::UsernameTooLong)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "but fails if we get an unknown response code" do
|
167
|
+
mock(HipChat::Room).post(anything, anything) {
|
168
|
+
OpenStruct.new(:code => 403)
|
169
|
+
}
|
170
|
+
|
171
|
+
lambda { room.send "", "" }.
|
172
|
+
should raise_error(HipChat::UnknownResponseCode)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'http_proxy' do
|
177
|
+
let(:proxy_user) { 'proxy_user' }
|
178
|
+
let(:proxy_pass) { 'proxy_pass' }
|
179
|
+
let(:proxy_host) { 'proxy.example.com' }
|
180
|
+
let(:proxy_port) { 2649 }
|
181
|
+
let(:proxy_url) { "http://#{proxy_user}:#{proxy_pass}@#{proxy_host}:#{proxy_port}" }
|
182
|
+
|
183
|
+
context 'specified by option of constructor' do
|
184
|
+
before do
|
185
|
+
HipChat::Client.new("blah", :http_proxy => proxy_url)
|
186
|
+
end
|
187
|
+
|
188
|
+
subject { HipChat::Client.default_options }
|
189
|
+
|
190
|
+
specify "Client's proxy settings should be changed" do
|
191
|
+
expect(subject[:http_proxyaddr]).to eql(proxy_host)
|
192
|
+
expect(subject[:http_proxyport]).to eql(proxy_port)
|
193
|
+
expect(subject[:http_proxyuser]).to eql(proxy_user)
|
194
|
+
expect(subject[:http_proxypass]).to eql(proxy_pass)
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "Room class's proxy" do
|
198
|
+
subject { HipChat::Room.default_options }
|
199
|
+
|
200
|
+
specify "proxy settings should be changed" do
|
201
|
+
expect(subject[:http_proxyaddr]).to eql(proxy_host)
|
202
|
+
expect(subject[:http_proxyport]).to eql(proxy_port)
|
203
|
+
expect(subject[:http_proxyuser]).to eql(proxy_user)
|
204
|
+
expect(subject[:http_proxypass]).to eql(proxy_pass)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'hipchat-chef'
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.mock_with :rr
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hipchat-chef
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HipChat/Atlassian
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rr
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rdoc
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>'
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.4.2
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>'
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.4.2
|
111
|
+
description: Ruby library to interact with HipChat
|
112
|
+
email:
|
113
|
+
- support@hipchat.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .document
|
119
|
+
- .gitignore
|
120
|
+
- .travis.yml
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE
|
123
|
+
- README.textile
|
124
|
+
- Rakefile
|
125
|
+
- hipchat-chef.gemspec
|
126
|
+
- lib/hipchat-chef.rb
|
127
|
+
- lib/hipchat-chef/capistrano.rb
|
128
|
+
- lib/hipchat-chef/chef.rb
|
129
|
+
- lib/hipchat-chef/rails3_tasks.rb
|
130
|
+
- lib/hipchat-chef/railtie.rb
|
131
|
+
- lib/hipchat-chef/version.rb
|
132
|
+
- spec/example/history.json
|
133
|
+
- spec/hipchat_spec.rb
|
134
|
+
- spec/spec.opts
|
135
|
+
- spec/spec_helper.rb
|
136
|
+
homepage: https://github.com/hipchat/hipchat-rb
|
137
|
+
licenses:
|
138
|
+
- MIT
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ! '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 1.9.3
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.1.11
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: Ruby library to interact with HipChat
|
160
|
+
test_files:
|
161
|
+
- spec/example/history.json
|
162
|
+
- spec/hipchat_spec.rb
|
163
|
+
- spec/spec.opts
|
164
|
+
- spec/spec_helper.rb
|