tc4r 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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/bin/tc +4 -0
- data/bin/tc-setup +3 -0
- data/lib/tc4r.rb +11 -0
- data/lib/tc4r/build.rb +27 -0
- data/lib/tc4r/build_type.rb +32 -0
- data/lib/tc4r/client.rb +109 -0
- data/lib/tc4r/helpers.rb +23 -0
- data/lib/tc4r/version.rb +3 -0
- data/lib/tc4r_base.rb +120 -0
- data/lib/tc4r_setup.rb +48 -0
- data/spec/client_spec.rb +105 -0
- data/spec/requests/build_5733.json +1 -0
- data/spec/requests/build_types.json +36 -0
- data/spec/requests/builds_bt1.json +167 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/tc_client_spec.rb +5 -0
- data/tc4r.gemspec +28 -0
- metadata +204 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Paul Morton
|
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,29 @@
|
|
1
|
+
# Tc4r
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'tc4r'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install tc4r
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/tc
ADDED
data/bin/tc-setup
ADDED
data/lib/tc4r.rb
ADDED
data/lib/tc4r/build.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Tc4r
|
2
|
+
class Build
|
3
|
+
include ActiveModel::Serializers::JSON
|
4
|
+
self.include_root_in_json = false
|
5
|
+
|
6
|
+
attr_reader :id, :number, :status, :build_type_id, :start_date, :href, :client
|
7
|
+
def initialize(options,client)
|
8
|
+
options = Tc4r::Helpers.symbolize(options)
|
9
|
+
@id = options[:id]
|
10
|
+
@number = options[:number]
|
11
|
+
@status = options[:status]
|
12
|
+
@build_type_id = options[:build_type_id]
|
13
|
+
@start_date = Time.parse(options[:start_date])
|
14
|
+
@href = options[:href]
|
15
|
+
@client = client
|
16
|
+
end
|
17
|
+
|
18
|
+
def attributes
|
19
|
+
{ :id => @id, :number => @number, :status => @status, :build_type_id => @build_type_id, :start_date => @start_date, :href => @href }
|
20
|
+
end
|
21
|
+
|
22
|
+
def download_file(file, options = {})
|
23
|
+
client.download_file(build_type_id,number,file,options)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Tc4r
|
2
|
+
class BuildType
|
3
|
+
include ActiveModel::Serializers::JSON
|
4
|
+
self.include_root_in_json = false
|
5
|
+
|
6
|
+
attr_reader :id,:name,:project_name,:project_id, :href, :client
|
7
|
+
|
8
|
+
def initialize(options = {},client)
|
9
|
+
options = Tc4r::Helpers.symbolize(options)
|
10
|
+
@id = options[:id]
|
11
|
+
@name = options[:name]
|
12
|
+
@project_name = options[:project_name] || options[:project][:name]
|
13
|
+
@project_id = options[:project_id] || options[:project][:id]
|
14
|
+
@href = options[:href]
|
15
|
+
@client = client
|
16
|
+
end
|
17
|
+
|
18
|
+
def attributes
|
19
|
+
{ :id => @id, :name => @name, :project_name => @project_name, :project_id => @project_id, :href => @href }
|
20
|
+
end
|
21
|
+
|
22
|
+
def builds
|
23
|
+
client.query_builds(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def build(number)
|
27
|
+
client.build(id,number)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/tc4r/client.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'nestful'
|
3
|
+
require 'commander'
|
4
|
+
module Tc4r
|
5
|
+
|
6
|
+
class Client
|
7
|
+
attr_reader :server
|
8
|
+
attr_reader :port
|
9
|
+
attr_reader :username
|
10
|
+
attr_reader :password
|
11
|
+
attr_reader :transport
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
default_options = { :server => 'localhost',
|
15
|
+
:port => 8111,
|
16
|
+
:username => nil,
|
17
|
+
:password => nil,
|
18
|
+
:transport => :http
|
19
|
+
}
|
20
|
+
options = default_options.merge(options)
|
21
|
+
|
22
|
+
@server = options[:server]
|
23
|
+
@port = options[:port]
|
24
|
+
@username = options[:username]
|
25
|
+
@password = options[:password]
|
26
|
+
@transport = options[:transport]
|
27
|
+
end
|
28
|
+
|
29
|
+
def base_url
|
30
|
+
@base_url ||= "#{transport}://#{server}:#{port}/httpAuth"
|
31
|
+
end
|
32
|
+
|
33
|
+
def rest_url(path)
|
34
|
+
"#{base_url}/app/rest/#{path}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def download_url(path)
|
38
|
+
"#{base_url}/repository/download/#{path}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge_options(options)
|
42
|
+
{ :user => username,
|
43
|
+
:password => password,
|
44
|
+
:auth_type => :basic }.merge(options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_types
|
48
|
+
bts = Nestful.get rest_url('buildTypes') , merge_options( :format => :json )
|
49
|
+
bts['buildType'].collect do |bt|
|
50
|
+
BuildType.new(Tc4r::Helpers.sym_score(bt), self)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_type(bt)
|
55
|
+
build_type = Nestful.get rest_url("buildTypes/id:#{bt}") , merge_options( :format => :json )
|
56
|
+
BuildType.new(Tc4r::Helpers.sym_score(build_type), self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def query_builds(bt, options = {})
|
60
|
+
parameters = {}
|
61
|
+
parameters[:status] = 'SUCCESS' if options[:status] == :success
|
62
|
+
parameters[:status] = 'ERROR' if options[:status] == :error
|
63
|
+
parameters[:tag] = options[:tag] if options[:tag]
|
64
|
+
builds = Nestful.get rest_url("buildTypes/id:#{bt}/builds") , merge_options( :format => :json, :params => parameters )
|
65
|
+
builds['build'].collect do |build|
|
66
|
+
Build.new(Tc4r::Helpers.sym_score(build),self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def build(bt,number)
|
71
|
+
build = Nestful.get rest_url("buildTypes/id:#{bt}/builds/number:#{number}") , merge_options( :format => :json )
|
72
|
+
Tc4r::Build.new(Tc4r::Helpers.sym_score(build), self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def download_file(bt,number,file,options = {})
|
76
|
+
default_options = {:with_progress => true, :destination => File.expand_path("./#{File.basename(file)}")}
|
77
|
+
options = default_options.merge(options)
|
78
|
+
|
79
|
+
download_parameters = {:buffer => true}
|
80
|
+
if options[:with_progress]
|
81
|
+
download_parameters[:progress] = progress_bar
|
82
|
+
end
|
83
|
+
|
84
|
+
build = build(bt,number)
|
85
|
+
f = Nestful.get download_url("#{bt}/#{build.id}:id/#{file}"), merge_options( download_parameters )
|
86
|
+
f.close
|
87
|
+
FileUtils.mv(f.path,options[:destination])
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
def progress_bar
|
92
|
+
Proc.new do |conn, total, size|
|
93
|
+
@progress ||= Commander::UI::ProgressBar.new total, :title => "Downloading Build", :complete_message => "File download complete"
|
94
|
+
@last_pct ||= 0
|
95
|
+
current_pct = ((size.to_f/total.to_f)*100).floor
|
96
|
+
@progress.instance_variable_set('@step',size)
|
97
|
+
if current_pct != @last_pct
|
98
|
+
@progress.show
|
99
|
+
@last_pct = current_pct
|
100
|
+
end
|
101
|
+
|
102
|
+
if @progress.finished?
|
103
|
+
@progress = nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
data/lib/tc4r/helpers.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tc4r
|
2
|
+
module Helpers
|
3
|
+
def self.symbolize(obj)
|
4
|
+
return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = symbolize(v); memo} if obj.is_a? Hash
|
5
|
+
return obj.inject([]){|memo,v | memo << symbolize(v); memo} if obj.is_a? Array
|
6
|
+
return obj
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.underscore(obj)
|
10
|
+
obj.gsub(/::/, '/').
|
11
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
12
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
13
|
+
tr("-", "_").
|
14
|
+
downcase
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.sym_score(obj)
|
18
|
+
return obj.inject({}){|memo,(k,v)| memo[k.underscore.to_sym] = symbolize(v); memo} if obj.is_a? Hash
|
19
|
+
return obj
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/tc4r/version.rb
ADDED
data/lib/tc4r_base.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'tc4r'
|
2
|
+
require 'terminal-table'
|
3
|
+
|
4
|
+
# :name is optional, otherwise uses the basename of this executable
|
5
|
+
program :name, 'tc4r'
|
6
|
+
program :version, '1.0.0'
|
7
|
+
program :description, 'Teamcity Ruby Client'
|
8
|
+
|
9
|
+
default_command :useage
|
10
|
+
|
11
|
+
command :useage do |c|
|
12
|
+
c.syntax = 'tc4r useage'
|
13
|
+
c.description = 'Get useage'
|
14
|
+
|
15
|
+
c.action do |args, options|
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_config(file)
|
21
|
+
if File.exist? File.expand_path(file)
|
22
|
+
return Tc4r::Helpers.symbolize(YAML.load(File.read(File.expand_path(file))))
|
23
|
+
else
|
24
|
+
abort ("Configuration file does not exist #{file}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
global_option('-c', '--config FILE', 'Load config data for your commands to use') do |file|
|
29
|
+
$config = load_config(file)
|
30
|
+
end
|
31
|
+
|
32
|
+
unless $config
|
33
|
+
$config = load_config('~/.teamcity.yml')
|
34
|
+
end
|
35
|
+
|
36
|
+
command :bt do |c|
|
37
|
+
c.syntax = 'tc4r bt'
|
38
|
+
c.description = 'List all build types'
|
39
|
+
c.option '--format FORMAT', String, 'Output format (TEXT)|JSON'
|
40
|
+
|
41
|
+
c.action do |args, options|
|
42
|
+
tc = Tc4r::Client.new($config)
|
43
|
+
format = options.format || 'text'
|
44
|
+
format = format.downcase.to_sym
|
45
|
+
|
46
|
+
case format
|
47
|
+
when :json
|
48
|
+
say tc.build_types.to_json
|
49
|
+
else
|
50
|
+
table = Terminal::Table.new :headings => ['ID','Name','Project'] do |t|
|
51
|
+
tc.build_types.each do |build|
|
52
|
+
t.add_row [build.id,build.name,build.project_name]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
puts table
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
command :builds do |c|
|
61
|
+
c.syntax = 'tc4r builds'
|
62
|
+
c.description = 'List all builds for a build type'
|
63
|
+
c.option '--bt BUILD_TYPE_ID', String, 'The build type ID to list builds for'
|
64
|
+
c.option '--format FORMAT', String, 'Output format (TEXT)|JSON'
|
65
|
+
c.option '--status STRING', String, 'Status of the build (BOTH)|ERROR|SUCCESS'
|
66
|
+
|
67
|
+
c.action do |args, options|
|
68
|
+
options.default :format => 'text'
|
69
|
+
options.default :status => 'both'
|
70
|
+
|
71
|
+
tc = Tc4r::Client.new($config)
|
72
|
+
|
73
|
+
format = options.format.downcase.to_sym
|
74
|
+
|
75
|
+
params = {}
|
76
|
+
|
77
|
+
status = options.status
|
78
|
+
status = status.downcase.to_sym
|
79
|
+
|
80
|
+
case status
|
81
|
+
when :error
|
82
|
+
params[:status] = :error
|
83
|
+
when :success
|
84
|
+
params[:status] = :success
|
85
|
+
end
|
86
|
+
|
87
|
+
case format
|
88
|
+
when :json
|
89
|
+
say tc.build_type(options.bt).builds.to_json
|
90
|
+
else
|
91
|
+
table = Terminal::Table.new :headings => ['ID','Number','Status','Start Date'] do |t|
|
92
|
+
tc.build_type(options.bt).builds.each do |build|
|
93
|
+
t.add_row [build.id,build.number,build.status,build.start_date]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
puts table
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
command :download do |c|
|
103
|
+
c.syntax = 'tc4r download'
|
104
|
+
c.description = 'Download a file from the build'
|
105
|
+
c.option '--bt BUILD_TYPE_ID', String, 'The build type ID to list builds for'
|
106
|
+
c.option '--number NUMBER', String, 'The build version number'
|
107
|
+
c.option '--file FILE', String, 'The file to download'
|
108
|
+
c.option '--dest FILE', String, 'The destination file name'
|
109
|
+
|
110
|
+
c.action do |args, options|
|
111
|
+
tc = Tc4r::Client.new($config)
|
112
|
+
bt = tc.build_type(options.bt)
|
113
|
+
build = bt.build(options.number)
|
114
|
+
download_options = {}
|
115
|
+
download_options[:destination] = options.dest if options.dest
|
116
|
+
|
117
|
+
tc.download_file(options.bt,options.number,options.file, download_options)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
data/lib/tc4r_setup.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'tc4r'
|
2
|
+
require 'commander/import'
|
3
|
+
|
4
|
+
# :name is optional, otherwise uses the basename of this executable
|
5
|
+
program :name, 'tc4r-setup'
|
6
|
+
program :version, '1.0.0'
|
7
|
+
program :description, 'Teamcity Ruby Client Setup Utility'
|
8
|
+
|
9
|
+
|
10
|
+
command :setup do |c|
|
11
|
+
c.syntax = 'tc4r bt'
|
12
|
+
c.description = 'List all build types'
|
13
|
+
c.option '--server SERVER', String, 'Teamcity Server'
|
14
|
+
c.option '--port PORT', Integer, 'The port to connect to'
|
15
|
+
c.option '--username USERNAME', String, 'Your teamcity username'
|
16
|
+
c.option '--password PASSWORD', String, 'Your teamcity password'
|
17
|
+
c.option '--transport (HTTP|HTTPS)', String, 'The transport to connect to teamcity'
|
18
|
+
|
19
|
+
c.action do |args, options|
|
20
|
+
if File.exist? File.expand_path('~/.teamcity.yml')
|
21
|
+
old_config = YAML.load(File.read(File.expand_path('~/.teamcity.yml')))
|
22
|
+
else
|
23
|
+
old_config = { 'server' => 'localhost',
|
24
|
+
'port' => 8111,
|
25
|
+
'transport' => 'http' }
|
26
|
+
end
|
27
|
+
|
28
|
+
c = {}
|
29
|
+
c['server'] = options.server || ask("Teamcity Server [#{old_config['server']}]: ")
|
30
|
+
c['port'] = options.port || ask("Port[#{old_config ['port']}]: ").to_i
|
31
|
+
c['transport'] = options.transport || choice = choose("Transport:", 'http', 'https')
|
32
|
+
c['username'] = options.username || ask("Username [#{old_config['username']}]: ")
|
33
|
+
c['password'] = options.password || ask("Password: ") { |q| q.echo = "*" }
|
34
|
+
|
35
|
+
c.each do |k,v|
|
36
|
+
if v.is_a? String and v.empty?
|
37
|
+
c[k] = old_config[k]
|
38
|
+
elsif v.is_a? Fixnum and v.eql? 0
|
39
|
+
c[k] = old_config[k]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
File.open(File.expand_path('~/.teamcity.yml'), "w") {|file|
|
44
|
+
YAML.dump(c,file)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Tc4r::Client do
|
4
|
+
let(:client) { Tc4r::Client.new( :username => 'username', :password => 'password') }
|
5
|
+
|
6
|
+
it 'should initialize and setup attr_readers' do
|
7
|
+
client = Tc4r::Client.new(:server => 'notlocalhost',
|
8
|
+
:port => 8112,
|
9
|
+
:username => 'username',
|
10
|
+
:password => 'password',
|
11
|
+
:transport => :https)
|
12
|
+
client.server.should == 'notlocalhost'
|
13
|
+
client.port.should == 8112
|
14
|
+
client.password.should == 'password'
|
15
|
+
client.transport.should == :https
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should merge options into defaults' do
|
19
|
+
client = Tc4r::Client.new( :port => 8112,
|
20
|
+
:username => 'username',
|
21
|
+
:password => 'password')
|
22
|
+
client.port.should == 8112
|
23
|
+
client.server.should == 'localhost'
|
24
|
+
client.username.should == 'username'
|
25
|
+
client.password.should == 'password'
|
26
|
+
client.transport.should == :http
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should generate urls' do
|
30
|
+
client = Tc4r::Client.new()
|
31
|
+
client.base_url.should == 'http://localhost:8111/httpAuth'
|
32
|
+
client.rest_url('some_endpoint').should == 'http://localhost:8111/httpAuth/app/rest/some_endpoint'
|
33
|
+
client.download_url('some_endpoint').should == 'http://localhost:8111/httpAuth/repository/download/some_endpoint'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should merge global parameters' do
|
37
|
+
options = client.merge_options(:test_parameter => 'test')
|
38
|
+
options[:test_parameter].should == 'test'
|
39
|
+
options[:user].should == 'username'
|
40
|
+
options[:password].should == 'password'
|
41
|
+
options[:auth_type].should == :basic
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should query for successful builds for a build type' do
|
45
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds?status=SUCCESS", :body => File.read('spec/requests/builds_bt1.json'), :content_type => "application/json")
|
46
|
+
build_types = client.query_builds 'bt1', :status => :success
|
47
|
+
FakeWeb.should have_requested(:get, 'http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds?status=SUCCESS')
|
48
|
+
build_types.each do |b|
|
49
|
+
b.should be_a_kind_of Tc4r::Build
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should query for errored builds for a build type' do
|
54
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds?status=ERROR", :body => File.read('spec/requests/builds_bt1.json'), :content_type => "application/json")
|
55
|
+
build_types = client.query_builds 'bt1', :status => :error
|
56
|
+
FakeWeb.should have_requested(:get, 'http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds?status=ERROR')
|
57
|
+
build_types.each do |b|
|
58
|
+
b.should be_a_kind_of Tc4r::Build
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
it 'should query build types' do
|
64
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes", :body => File.read('spec/requests/build_types.json'), :content_type => "application/json")
|
65
|
+
build_types = client.build_types
|
66
|
+
FakeWeb.should have_requested(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes")
|
67
|
+
build_types.each do |bt|
|
68
|
+
bt.should be_a_kind_of Tc4r::BuildType
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should query builds for a build type' do
|
73
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds", :body => File.read('spec/requests/builds_bt1.json'), :content_type => "application/json")
|
74
|
+
build_types = client.query_builds 'bt1'
|
75
|
+
FakeWeb.should have_requested(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds")
|
76
|
+
build_types.each do |b|
|
77
|
+
b.should be_a_kind_of Tc4r::Build
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should get a specific build number' do
|
82
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds/number:3.0.85", :body => File.read('spec/requests/build_5733.json'), :content_type => "application/json")
|
83
|
+
build = client.build 'bt1', '3.0.85'
|
84
|
+
FakeWeb.should have_requested(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds/number:3.0.85")
|
85
|
+
build.should be_a_kind_of Tc4r::Build
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should download a build to a specific destination' do
|
89
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds/number:3.0.85", :body => File.read('spec/requests/build_5733.json'), :content_type => "application/json")
|
90
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/repository/download/bt1/5733:id/test.zip", :body => {}.to_json, :content_length => 1234 )
|
91
|
+
FileUtils.stub(:mv) {}
|
92
|
+
FileUtils.should_receive(:mv).with(kind_of(String),'/tmp/test.zip')
|
93
|
+
client.download_file 'bt1', '3.0.85', 'test.zip', {:destination => '/tmp/test.zip'}
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should download a build to a my working directory' do
|
97
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/app/rest/buildTypes/id:bt1/builds/number:3.0.85", :body => File.read('spec/requests/build_5733.json'), :content_type => "application/json")
|
98
|
+
FakeWeb.register_uri(:get, "http://username:password@localhost:8111/httpAuth/repository/download/bt1/5733:id/test.zip", :body => {}.to_json, :content_length => 1234 )
|
99
|
+
FileUtils.stub(:mv) {}
|
100
|
+
FileUtils.should_receive(:mv).with(kind_of(String),File.expand_path('./test.zip'))
|
101
|
+
client.download_file 'bt1', '3.0.85', 'test.zip'
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"id":5733,"number":"3.0.85","status":"SUCCESS","href":"/httpAuth/app/rest/builds/id:5733","webUrl":"http://localhost:8111/viewLog.html?buildId=5733&buildTypeId=bt22","personal":false,"history":false,"pinned":false,"statusText":"Tests passed: 258","buildType":{"id":"bt1","name":"Product","href":"/httpAuth/app/rest/buildTypes/id:bt1","projectName":"Product","projectId":"project4","webUrl":"http://localhost:8111/viewType.html?buildTypeId=bt22"},"startDate":"20120824T094107-0700","finishDate":"20120824T095006-0700","agent":{"href":"/httpAuth/app/rest/agents/id:15","id":15,"name":"localhost"},"tags":null,"properties":null,"snapshot-dependencies":null,"artifact-dependencies":null,"revisions":{"revision":[{"version":"69748fea9e0aaf358ba227060107c4025cd6fb47","vcs-root-instance":{"id":"4843","vcs-root-id":"58","name":"rails","href":"/httpAuth/app/rest/vcs-roots/id:58/instances/id:4843"}}]},"triggered":{"type":"vcs","details":"jetbrains.git","date":"20120824T094107-0700"},"changes":{"count":2,"href":"/httpAuth/app/rest/changes?build=id:5733"}}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"buildType":[
|
3
|
+
{
|
4
|
+
"id":"bt1",
|
5
|
+
"name":"Code Analysis",
|
6
|
+
"href":"/httpAuth/app/rest/buildTypes/id:bt1",
|
7
|
+
"projectName":"Code Analysis",
|
8
|
+
"projectId":"project1",
|
9
|
+
"webUrl":"http://localhost:8111/viewType.html?buildTypeId=bt1"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"id":"bt2",
|
13
|
+
"name":"Product",
|
14
|
+
"href":"/httpAuth/app/rest/buildTypes/id:bt3",
|
15
|
+
"projectName":"Product",
|
16
|
+
"projectId":"project2",
|
17
|
+
"webUrl":"http://localhost:8111/viewType.html?buildTypeId=bt2"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"id":"bt3",
|
21
|
+
"name":"Tools",
|
22
|
+
"href":"/httpAuth/app/rest/buildTypes/id:bt2",
|
23
|
+
"projectName":"Tools",
|
24
|
+
"projectId":"project3",
|
25
|
+
"webUrl":"http://localhost:8111/viewType.html?buildTypeId=bt3"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"id":"bt4",
|
29
|
+
"name":"Deployment",
|
30
|
+
"href":"/httpAuth/app/rest/buildTypes/id:bt6",
|
31
|
+
"projectName":"Deployment",
|
32
|
+
"projectId":"project4",
|
33
|
+
"webUrl":"http://localhost:8111/viewType.html?buildTypeId=bt4"
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}
|
@@ -0,0 +1,167 @@
|
|
1
|
+
{
|
2
|
+
"count":18,
|
3
|
+
"build":[
|
4
|
+
{
|
5
|
+
"id":5733,
|
6
|
+
"number":"3.0.85",
|
7
|
+
"status":"SUCCESS",
|
8
|
+
"buildTypeId":"bt1",
|
9
|
+
"startDate":"20120824T094107-0700",
|
10
|
+
"href":"/httpAuth/app/rest/builds/id:5733",
|
11
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5733&buildTypeId=bt1"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"id":5731,
|
15
|
+
"number":"3.0.84",
|
16
|
+
"status":"SUCCESS",
|
17
|
+
"buildTypeId":"bt1",
|
18
|
+
"startDate":"20120823T163729-0700",
|
19
|
+
"href":"/httpAuth/app/rest/builds/id:5731",
|
20
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5731&buildTypeId=bt1"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"id":5730,
|
24
|
+
"number":"3.0.83",
|
25
|
+
"status":"FAILURE",
|
26
|
+
"buildTypeId":"bt1",
|
27
|
+
"startDate":"20120823T155053-0700",
|
28
|
+
"href":"/httpAuth/app/rest/builds/id:5730",
|
29
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5730&buildTypeId=bt1"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"id":5724,
|
33
|
+
"number":"3.0.82",
|
34
|
+
"status":"SUCCESS",
|
35
|
+
"buildTypeId":"bt1",
|
36
|
+
"startDate":"20120823T114241-0700",
|
37
|
+
"href":"/httpAuth/app/rest/builds/id:5724",
|
38
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5724&buildTypeId=bt1"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"id":5720,
|
42
|
+
"number":"3.0.80",
|
43
|
+
"status":"SUCCESS",
|
44
|
+
"buildTypeId":"bt1",
|
45
|
+
"startDate":"20120822T202718-0700",
|
46
|
+
"href":"/httpAuth/app/rest/builds/id:5720",
|
47
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5720&buildTypeId=bt1"
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"id":5719,
|
51
|
+
"number":"3.0.79",
|
52
|
+
"status":"SUCCESS",
|
53
|
+
"buildTypeId":"bt1",
|
54
|
+
"startDate":"20120822T201451-0700",
|
55
|
+
"href":"/httpAuth/app/rest/builds/id:5719",
|
56
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5719&buildTypeId=bt1"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"id":5717,
|
60
|
+
"number":"1.0.78",
|
61
|
+
"status":"SUCCESS",
|
62
|
+
"buildTypeId":"bt1",
|
63
|
+
"startDate":"20120822T193726-0700",
|
64
|
+
"href":"/httpAuth/app/rest/builds/id:5717",
|
65
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5717&buildTypeId=bt1"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"id":5716,
|
69
|
+
"number":"1.0.77",
|
70
|
+
"status":"FAILURE",
|
71
|
+
"buildTypeId":"bt1",
|
72
|
+
"startDate":"20120822T165610-0700",
|
73
|
+
"href":"/httpAuth/app/rest/builds/id:5716",
|
74
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5716&buildTypeId=bt1"
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"id":5715,
|
78
|
+
"number":"1.0.76",
|
79
|
+
"status":"FAILURE",
|
80
|
+
"buildTypeId":"bt1",
|
81
|
+
"startDate":"20120822T165101-0700",
|
82
|
+
"href":"/httpAuth/app/rest/builds/id:5715",
|
83
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5715&buildTypeId=bt1"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"id":5369,
|
87
|
+
"number":"1.0.30",
|
88
|
+
"status":"ERROR",
|
89
|
+
"buildTypeId":"bt1",
|
90
|
+
"startDate":"20120628T134853-0700",
|
91
|
+
"href":"/httpAuth/app/rest/builds/id:5369",
|
92
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5369&buildTypeId=bt1"
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"id":5368,
|
96
|
+
"number":"1.0.29",
|
97
|
+
"status":"ERROR",
|
98
|
+
"buildTypeId":"bt1",
|
99
|
+
"startDate":"20120628T134635-0700",
|
100
|
+
"href":"/httpAuth/app/rest/builds/id:5368",
|
101
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5368&buildTypeId=bt1"
|
102
|
+
},
|
103
|
+
{
|
104
|
+
"id":5362,
|
105
|
+
"number":"1.0.27",
|
106
|
+
"status":"ERROR",
|
107
|
+
"buildTypeId":"bt1",
|
108
|
+
"startDate":"20120628T100316-0700",
|
109
|
+
"href":"/httpAuth/app/rest/builds/id:5362",
|
110
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5362&buildTypeId=bt1"
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"id":5361,
|
114
|
+
"number":"1.0.26",
|
115
|
+
"status":"ERROR",
|
116
|
+
"buildTypeId":"bt1",
|
117
|
+
"startDate":"20120628T095945-0700",
|
118
|
+
"href":"/httpAuth/app/rest/builds/id:5361",
|
119
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5361&buildTypeId=bt1"
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"id":5360,
|
123
|
+
"number":"1.0.25",
|
124
|
+
"status":"ERROR",
|
125
|
+
"buildTypeId":"bt1",
|
126
|
+
"startDate":"20120628T095039-0700",
|
127
|
+
"href":"/httpAuth/app/rest/builds/id:5360",
|
128
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5360&buildTypeId=bt1"
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"id":5359,
|
132
|
+
"number":"1.0.24",
|
133
|
+
"status":"ERROR",
|
134
|
+
"buildTypeId":"bt1",
|
135
|
+
"startDate":"20120628T094752-0700",
|
136
|
+
"href":"/httpAuth/app/rest/builds/id:5359",
|
137
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5359&buildTypeId=bt1"
|
138
|
+
},
|
139
|
+
{
|
140
|
+
"id":5358,
|
141
|
+
"number":"1.0.23",
|
142
|
+
"status":"ERROR",
|
143
|
+
"buildTypeId":"bt1",
|
144
|
+
"startDate":"20120628T094616-0700",
|
145
|
+
"href":"/httpAuth/app/rest/builds/id:5358",
|
146
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5358&buildTypeId=bt1"
|
147
|
+
},
|
148
|
+
{
|
149
|
+
"id":5357,
|
150
|
+
"number":"1.0.22",
|
151
|
+
"status":"ERROR",
|
152
|
+
"buildTypeId":"bt1",
|
153
|
+
"startDate":"20120628T094510-0700",
|
154
|
+
"href":"/httpAuth/app/rest/builds/id:5357",
|
155
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5357&buildTypeId=bt1"
|
156
|
+
},
|
157
|
+
{
|
158
|
+
"id":5356,
|
159
|
+
"number":"1.0.21",
|
160
|
+
"status":"ERROR",
|
161
|
+
"buildTypeId":"bt1",
|
162
|
+
"startDate":"20120628T083310-0700",
|
163
|
+
"href":"/httpAuth/app/rest/builds/id:5356",
|
164
|
+
"webUrl":"http://localhost:8111/viewLog.html?buildId=5356&buildTypeId=bt1"
|
165
|
+
}
|
166
|
+
]
|
167
|
+
}
|
data/spec/spec_helper.rb
ADDED
data/tc4r.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tc4r/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Paul Morton"]
|
6
|
+
gem.email = ["pmorton@biaprotect.com"]
|
7
|
+
gem.description = %q{Teamcity Client for Ruby}
|
8
|
+
gem.summary = %q{A Teamcity Client for Ruby}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "tc4r"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.bindir = ['bin']
|
17
|
+
gem.executables = ['tc', 'tc-setup']
|
18
|
+
gem.version = Tc4r::VERSION
|
19
|
+
gem.add_dependency 'commander'
|
20
|
+
gem.add_dependency "nestful"
|
21
|
+
gem.add_dependency 'terminal-table'
|
22
|
+
gem.add_dependency 'activemodel'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'rspec'
|
25
|
+
gem.add_development_dependency 'fakeweb'
|
26
|
+
gem.add_development_dependency 'fakeweb-matcher'
|
27
|
+
gem.add_development_dependency 'simplecov'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tc4r
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Paul Morton
|
9
|
+
autorequire:
|
10
|
+
bindir:
|
11
|
+
- bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-08-27 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: commander
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: nestful
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: terminal-table
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: activemodel
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: rspec
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: fakeweb
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: fakeweb-matcher
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: simplecov
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
description: Teamcity Client for Ruby
|
144
|
+
email:
|
145
|
+
- pmorton@biaprotect.com
|
146
|
+
executables:
|
147
|
+
- tc
|
148
|
+
- tc-setup
|
149
|
+
extensions: []
|
150
|
+
extra_rdoc_files: []
|
151
|
+
files:
|
152
|
+
- .gitignore
|
153
|
+
- Gemfile
|
154
|
+
- LICENSE
|
155
|
+
- README.md
|
156
|
+
- Rakefile
|
157
|
+
- bin/tc
|
158
|
+
- bin/tc-setup
|
159
|
+
- lib/tc4r.rb
|
160
|
+
- lib/tc4r/build.rb
|
161
|
+
- lib/tc4r/build_type.rb
|
162
|
+
- lib/tc4r/client.rb
|
163
|
+
- lib/tc4r/helpers.rb
|
164
|
+
- lib/tc4r/version.rb
|
165
|
+
- lib/tc4r_base.rb
|
166
|
+
- lib/tc4r_setup.rb
|
167
|
+
- spec/client_spec.rb
|
168
|
+
- spec/requests/build_5733.json
|
169
|
+
- spec/requests/build_types.json
|
170
|
+
- spec/requests/builds_bt1.json
|
171
|
+
- spec/spec_helper.rb
|
172
|
+
- spec/tc_client_spec.rb
|
173
|
+
- tc4r.gemspec
|
174
|
+
homepage: ''
|
175
|
+
licenses: []
|
176
|
+
post_install_message:
|
177
|
+
rdoc_options: []
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ! '>='
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
none: false
|
188
|
+
requirements:
|
189
|
+
- - ! '>='
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
requirements: []
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 1.8.24
|
195
|
+
signing_key:
|
196
|
+
specification_version: 3
|
197
|
+
summary: A Teamcity Client for Ruby
|
198
|
+
test_files:
|
199
|
+
- spec/client_spec.rb
|
200
|
+
- spec/requests/build_5733.json
|
201
|
+
- spec/requests/build_types.json
|
202
|
+
- spec/requests/builds_bt1.json
|
203
|
+
- spec/spec_helper.rb
|
204
|
+
- spec/tc_client_spec.rb
|