tc4r 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tc4r.gemspec
4
+ gemspec
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.
@@ -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
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
data/bin/tc ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'commander/import'
3
+ require 'tc4r_base'
4
+
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'commander/import'
3
+ require 'tc4r_setup'
@@ -0,0 +1,11 @@
1
+ require "tc4r/version"
2
+
3
+ require 'active_model'
4
+
5
+ require 'tc4r/helpers'
6
+ require 'tc4r/build_type'
7
+ require 'tc4r/build'
8
+
9
+ require 'nestful'
10
+
11
+ require 'tc4r/client'
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module Tc4r
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
+
@@ -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
@@ -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
+ }
@@ -0,0 +1,5 @@
1
+ require 'fakeweb'
2
+ require 'tc4r'
3
+ require 'fakeweb_matcher'
4
+ require 'simplecov'
5
+ SimpleCov.start
@@ -0,0 +1,5 @@
1
+ require_relative 'spec_helper.rb'
2
+
3
+ describe Tc4r::Client do
4
+
5
+ end
@@ -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