sbci 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Guardfile +19 -0
- data/LICENSE +22 -0
- data/README.md +28 -0
- data/Rakefile +2 -0
- data/bin/sbci +51 -0
- data/lib/config.xml +103 -0
- data/lib/sbci.rb +145 -0
- data/lib/sbci/version.rb +3 -0
- data/sbci.gemspec +29 -0
- data/spec/.DS_Store +0 -0
- data/spec/fixtures/vcr_cassettes/delete.yml +42 -0
- data/spec/fixtures/vcr_cassettes/dump.yml +78 -0
- data/spec/fixtures/vcr_cassettes/publish.yml +160 -0
- data/spec/fixtures/vcr_cassettes/republish.yml +232 -0
- data/spec/sbci_cli_spec.rb +21 -0
- data/spec/sbci_spec.rb +151 -0
- data/spec/spec_helper.rb +12 -0
- metadata +190 -0
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
.jenkins/
|
7
|
+
spec/fixtures/.jenkins
|
8
|
+
spec/fixtures/jenkins
|
9
|
+
Gemfile.lock
|
10
|
+
InstalledFiles
|
11
|
+
_yardoc
|
12
|
+
coverage
|
13
|
+
doc/
|
14
|
+
lib/bundler/man
|
15
|
+
pkg
|
16
|
+
rdoc
|
17
|
+
spec/reports
|
18
|
+
test/tmp
|
19
|
+
test/version_tmp
|
20
|
+
tmp
|
21
|
+
/vendor/bundle
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
# Capybara request specs
|
17
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
18
|
+
end
|
19
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Egils Muzis
|
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,28 @@
|
|
1
|
+
# SBCI - Simply Business Continuous Integration
|
2
|
+
|
3
|
+
This command-line utility provides an easy way for Jenkins job configuration to be exported to disk.
|
4
|
+
Great for backup purposes and later restoring to the same or other Jenkins instances.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
### Through RVM global gemset (recommended)
|
9
|
+
|
10
|
+
rvm use gemset global
|
11
|
+
gem install sbci
|
12
|
+
|
13
|
+
### Or per project basis only - Gemfile
|
14
|
+
|
15
|
+
gem 'sbci'
|
16
|
+
|
17
|
+
## Example Usage
|
18
|
+
|
19
|
+
We recommend that you create a .jenkins directory checked into your project git repo to keep a backup of your Jenkins job configuration.
|
20
|
+
|
21
|
+
### Exporting / Backing up a job from your Jenkins server
|
22
|
+
sbci dump --host localhost --port 8080 --job-name development --path .jenkins
|
23
|
+
|
24
|
+
### Restoring / Updating a job from your backup
|
25
|
+
sbci publish --host localhost --port 8080 --job-name development --path .jenkins
|
26
|
+
|
27
|
+
### To view other commands
|
28
|
+
sbci --help
|
data/Rakefile
ADDED
data/bin/sbci
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
3
|
+
|
4
|
+
require 'trollop'
|
5
|
+
require 'sbci'
|
6
|
+
|
7
|
+
COMMANDS = %w(create dump publish delete)
|
8
|
+
|
9
|
+
opts = Trollop::options do
|
10
|
+
banner <<-EOS
|
11
|
+
Usage:
|
12
|
+
|
13
|
+
* Create a new configuration xml template file:
|
14
|
+
|
15
|
+
sbci create --job-name development --path .jenkins
|
16
|
+
|
17
|
+
* Dump a configuration xml from an existing project:
|
18
|
+
|
19
|
+
sbci dump --host localhost --port 8080 --job-name development --path .jenkins
|
20
|
+
|
21
|
+
* Publish a configuration xml to create a new Jenkins job:
|
22
|
+
|
23
|
+
sbci publish --host localhost --port 8080 --job-name development --path .jenkins
|
24
|
+
|
25
|
+
* Delete a Jenkins job:
|
26
|
+
|
27
|
+
sbci delete --host localhost --port 8080 --job-name development
|
28
|
+
|
29
|
+
* Force overwriting without getting prompt (e.g. create, publish, dump)
|
30
|
+
|
31
|
+
sbci dump --host localhost --port 8080 --job-name development --path .jenkins --force true
|
32
|
+
|
33
|
+
where [options] are:
|
34
|
+
|
35
|
+
EOS
|
36
|
+
opt :host, "Hostname", :type => String
|
37
|
+
opt :port, "Port number", :type => :int
|
38
|
+
opt :job_name, "Name of the Jenkins job", :type => String
|
39
|
+
opt :path, "Relative path", :type => String
|
40
|
+
opt :force, "Force overwriting"
|
41
|
+
end
|
42
|
+
|
43
|
+
cmd = ARGV.shift
|
44
|
+
|
45
|
+
if cmd == "debug"
|
46
|
+
puts YAML::dump(SBCI::Job.new(opts))
|
47
|
+
elsif COMMANDS.include?(cmd)
|
48
|
+
SBCI::Job.new(opts).send(cmd)
|
49
|
+
else
|
50
|
+
puts "Please enter a valid task name"
|
51
|
+
end
|
data/lib/config.xml
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
2
|
+
<project>
|
3
|
+
<actions/>
|
4
|
+
<description>_PROJECT_NAME_</description>
|
5
|
+
<logRotator>
|
6
|
+
<daysToKeep>1</daysToKeep>
|
7
|
+
<numToKeep>5</numToKeep>
|
8
|
+
<artifactDaysToKeep>-1</artifactDaysToKeep>
|
9
|
+
<artifactNumToKeep>-1</artifactNumToKeep>
|
10
|
+
</logRotator>
|
11
|
+
<keepDependencies>false</keepDependencies>
|
12
|
+
<properties>
|
13
|
+
<com.coravy.hudson.plugins.github.GithubProjectProperty>
|
14
|
+
<projectUrl>_PROJECT_URL_</projectUrl>
|
15
|
+
</com.coravy.hudson.plugins.github.GithubProjectProperty>
|
16
|
+
</properties>
|
17
|
+
<scm class="hudson.plugins.git.GitSCM">
|
18
|
+
<configVersion>2</configVersion>
|
19
|
+
<userRemoteConfigs>
|
20
|
+
<hudson.plugins.git.UserRemoteConfig>
|
21
|
+
<name></name>
|
22
|
+
<refspec></refspec>
|
23
|
+
<url>_GIT_REPO_</url>
|
24
|
+
</hudson.plugins.git.UserRemoteConfig>
|
25
|
+
</userRemoteConfigs>
|
26
|
+
<branches>
|
27
|
+
<hudson.plugins.git.BranchSpec>
|
28
|
+
<name>_BRANCH_NAME_</name>
|
29
|
+
</hudson.plugins.git.BranchSpec>
|
30
|
+
</branches>
|
31
|
+
<disableSubmodules>false</disableSubmodules>
|
32
|
+
<recursiveSubmodules>false</recursiveSubmodules>
|
33
|
+
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
|
34
|
+
<authorOrCommitter>false</authorOrCommitter>
|
35
|
+
<clean>false</clean>
|
36
|
+
<wipeOutWorkspace>false</wipeOutWorkspace>
|
37
|
+
<pruneBranches>false</pruneBranches>
|
38
|
+
<remotePoll>false</remotePoll>
|
39
|
+
<ignoreNotifyCommit>false</ignoreNotifyCommit>
|
40
|
+
<buildChooser class="hudson.plugins.git.util.DefaultBuildChooser"/>
|
41
|
+
<gitTool>Default</gitTool>
|
42
|
+
<submoduleCfg class="list"/>
|
43
|
+
<relativeTargetDir></relativeTargetDir>
|
44
|
+
<reference></reference>
|
45
|
+
<excludedRegions></excludedRegions>
|
46
|
+
<excludedUsers></excludedUsers>
|
47
|
+
<gitConfigName></gitConfigName>
|
48
|
+
<gitConfigEmail></gitConfigEmail>
|
49
|
+
<skipTag>false</skipTag>
|
50
|
+
<includedRegions></includedRegions>
|
51
|
+
<scmName></scmName>
|
52
|
+
</scm>
|
53
|
+
<canRoam>true</canRoam>
|
54
|
+
<disabled>false</disabled>
|
55
|
+
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
56
|
+
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
57
|
+
<triggers class="vector">
|
58
|
+
<com.cloudbees.jenkins.GitHubPushTrigger>
|
59
|
+
<spec></spec>
|
60
|
+
</com.cloudbees.jenkins.GitHubPushTrigger>
|
61
|
+
<hudson.triggers.SCMTrigger>
|
62
|
+
<spec>* * * * *</spec>
|
63
|
+
</hudson.triggers.SCMTrigger>
|
64
|
+
</triggers>
|
65
|
+
<concurrentBuild>false</concurrentBuild>
|
66
|
+
<builders>
|
67
|
+
<hudson.tasks.Shell>
|
68
|
+
<command>rvm --force gemset empty _PROJECT_NAME_ && bundle install</command>
|
69
|
+
</hudson.tasks.Shell>
|
70
|
+
<hudson.tasks.Shell>
|
71
|
+
<command>bundle exec rspec spec --format html -o doc/rspec.html</command>
|
72
|
+
</hudson.tasks.Shell>
|
73
|
+
</builders>
|
74
|
+
<publishers>
|
75
|
+
<hudson.tasks.ArtifactArchiver>
|
76
|
+
<artifacts>doc/*html</artifacts>
|
77
|
+
<latestOnly>false</latestOnly>
|
78
|
+
</hudson.tasks.ArtifactArchiver>
|
79
|
+
<htmlpublisher.HtmlPublisher>
|
80
|
+
<reportTargets>
|
81
|
+
<htmlpublisher.HtmlPublisherTarget>
|
82
|
+
<reportName>Rspec Report</reportName>
|
83
|
+
<reportDir>doc</reportDir>
|
84
|
+
<reportFiles>rspec.html</reportFiles>
|
85
|
+
<keepAll>true</keepAll>
|
86
|
+
<wrapperName>htmlpublisher-wrapper.html</wrapperName>
|
87
|
+
</htmlpublisher.HtmlPublisherTarget>
|
88
|
+
</reportTargets>
|
89
|
+
</htmlpublisher.HtmlPublisher>
|
90
|
+
<hudson.plugins.claim.ClaimPublisher/>
|
91
|
+
</publishers>
|
92
|
+
<buildWrappers>
|
93
|
+
<hudson.plugins.ansicolor.AnsiColorBuildWrapper/>
|
94
|
+
<ruby-proxy-object>
|
95
|
+
<ruby-object ruby-class="Jenkins::Plugin::Proxies::BuildWrapper" pluginid="rvm">
|
96
|
+
<object ruby-class="RvmWrapper" pluginid="rvm">
|
97
|
+
<impl pluginid="rvm" ruby-class="String">1.9.2-p290@_PROJECT_NAME_</impl>
|
98
|
+
</object>
|
99
|
+
<pluginid pluginid="rvm" ruby-class="String">rvm</pluginid>
|
100
|
+
</ruby-object>
|
101
|
+
</ruby-proxy-object>
|
102
|
+
</buildWrappers>
|
103
|
+
</project>
|
data/lib/sbci.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "rest_client"
|
3
|
+
require "grit"
|
4
|
+
require "uri"
|
5
|
+
require "rubygems"
|
6
|
+
require "sbci/version"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
module SBCI
|
10
|
+
|
11
|
+
INITIAL_CONFIG_PATH = "#{File.expand_path("../..",__FILE__)}/lib/config.xml"
|
12
|
+
MESSAGES = {
|
13
|
+
:config_dir_exists => "Config already exists for this project",
|
14
|
+
:config_already_exists => "Config file already exists and will be overwritten",
|
15
|
+
:config_already_published => "Config file is already published and will be overwritten"
|
16
|
+
}
|
17
|
+
|
18
|
+
def self.pwd
|
19
|
+
@pwd = Dir.pwd
|
20
|
+
end
|
21
|
+
|
22
|
+
class Job
|
23
|
+
|
24
|
+
def self.repo_name
|
25
|
+
conf = Grit::Config.new(get_repo)
|
26
|
+
conf["remote.origin.url"].gsub(/\.git$/,"").split("/").last
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.branch_name
|
30
|
+
Grit::Head.current(get_repo).name
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.get_repo
|
34
|
+
Grit::Repo.new(".")
|
35
|
+
end
|
36
|
+
|
37
|
+
ATTRIBUTES = [
|
38
|
+
:host, :port, :branch_name, :job_name, :path, :force
|
39
|
+
].freeze
|
40
|
+
|
41
|
+
DEFAULTS = {
|
42
|
+
:host => "localhost",
|
43
|
+
:port => 8080,
|
44
|
+
:path => "",
|
45
|
+
:job_name => self.repo_name,
|
46
|
+
:force => false
|
47
|
+
}
|
48
|
+
|
49
|
+
ATTRIBUTES.each do |attr|
|
50
|
+
attr_accessor attr
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(args = nil)
|
54
|
+
args.delete_if{ |k,v| v.nil? || v == ""} if args.is_a?(Hash)
|
55
|
+
args = args ? DEFAULTS.merge(args) : DEFAULTS
|
56
|
+
|
57
|
+
ATTRIBUTES.each do |attr|
|
58
|
+
if (args.key?(attr))
|
59
|
+
instance_variable_set("@#{attr}", args[attr])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create
|
65
|
+
prompt(SBCI::MESSAGES[:config_already_exists], config_exists?) do
|
66
|
+
FileUtils.cp(SBCI::INITIAL_CONFIG_PATH, config_file_path)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def publish
|
71
|
+
already_published = published?
|
72
|
+
url = if already_published
|
73
|
+
"#{host_with_port}/job/#{job_name}/config.xml"
|
74
|
+
else
|
75
|
+
"#{host_with_port}/createItem?name=#{job_name}"
|
76
|
+
end
|
77
|
+
prompt(SBCI::MESSAGES[:config_already_published], already_published) do
|
78
|
+
RestClient.post(URI.escape(url), File.read(config_file_path), :content_type => :xml)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def published?
|
83
|
+
begin
|
84
|
+
RestClient.get(URI.escape("#{host_with_port}/job/#{self.job_name}/config.xml"))
|
85
|
+
rescue
|
86
|
+
false
|
87
|
+
else
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def dump
|
93
|
+
prompt(SBCI::MESSAGES[:config_already_exists], config_exists?) do
|
94
|
+
response = RestClient.get(URI.escape("#{host_with_port}/job/#{self.job_name}/config.xml"))
|
95
|
+
File.open(config_file_path, "w") {|f| f.write(response.body) }
|
96
|
+
response
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def delete
|
101
|
+
begin
|
102
|
+
RestClient.post(URI.escape("#{host_with_port}/job/#{self.job_name}/doDelete"), {})
|
103
|
+
rescue RestClient::Found
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def config_file_path
|
109
|
+
File.join(config_file_dir, "#{self.job_name}.xml")
|
110
|
+
end
|
111
|
+
|
112
|
+
def config_file_dir
|
113
|
+
file_dir = File.join(SBCI.pwd, self.path)
|
114
|
+
FileUtils.mkdir_p(file_dir)
|
115
|
+
file_dir
|
116
|
+
end
|
117
|
+
|
118
|
+
def config_exists?
|
119
|
+
File.exists?(config_file_path)
|
120
|
+
end
|
121
|
+
|
122
|
+
def host_with_port
|
123
|
+
"#{host}:#{port}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def delete_config
|
127
|
+
FileUtils.rm(config_file_path) if File.exists?(config_file_path)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def prompt(message, condition = true, &block)
|
133
|
+
if !self.force && condition
|
134
|
+
message << "\nDo you want to continue [Y/n] ? "
|
135
|
+
print(message)
|
136
|
+
answer = gets
|
137
|
+
yield if answer.strip.downcase == "y"
|
138
|
+
else
|
139
|
+
yield
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/lib/sbci/version.rb
ADDED
data/sbci.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sbci/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.authors = ["Egils Muzis"]
|
6
|
+
s.email = ["egils.muzis@xbridge.com"]
|
7
|
+
s.description = "Utility to easily export or import and Jenkins job configuration"
|
8
|
+
s.summary = "Manage your Jenkins jobs through this easy to use command-line interface"
|
9
|
+
s.homepage = "https://github.com/simplybusiness/sbci"
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split($\)
|
12
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
14
|
+
s.name = "sbci"
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.version = SBCI::VERSION
|
17
|
+
|
18
|
+
s.add_dependency "rest-client"
|
19
|
+
s.add_dependency "grit"
|
20
|
+
s.add_dependency "trollop"
|
21
|
+
|
22
|
+
s.add_development_dependency "bahia"
|
23
|
+
s.add_development_dependency "guard"
|
24
|
+
s.add_development_dependency "guard-rspec"
|
25
|
+
s.add_development_dependency "growl"
|
26
|
+
s.add_development_dependency "rspec"
|
27
|
+
s.add_development_dependency "vcr"
|
28
|
+
s.add_development_dependency "webmock"
|
29
|
+
end
|
data/spec/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: http://localhost:8080/job/test_job/doDelete
|
6
|
+
body:
|
7
|
+
encoding: ASCII-8BIT
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*; q=0.5, application/xml'
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
Content-Length:
|
15
|
+
- '0'
|
16
|
+
Content-Type:
|
17
|
+
- application/x-www-form-urlencoded
|
18
|
+
User-Agent:
|
19
|
+
- Ruby
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 302
|
23
|
+
message: Found
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Winstone Servlet Engine v0.9.10
|
27
|
+
Location:
|
28
|
+
- http://localhost:8080/
|
29
|
+
Content-Length:
|
30
|
+
- '0'
|
31
|
+
Connection:
|
32
|
+
- Keep-Alive
|
33
|
+
Date:
|
34
|
+
- Mon, 02 Jul 2012 11:49:49 GMT
|
35
|
+
X-Powered-By:
|
36
|
+
- Servlet/2.5 (Winstone/0.9.10)
|
37
|
+
body:
|
38
|
+
encoding: US-ASCII
|
39
|
+
string: ''
|
40
|
+
http_version: !!null
|
41
|
+
recorded_at: Mon, 02 Jul 2012 11:49:49 GMT
|
42
|
+
recorded_with: VCR 2.2.1
|