teamcity-ruby-client 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +15 -1
  3. data/README.md +4 -2
  4. data/lib/teamcity.rb +1 -0
  5. data/lib/teamcity/client/build_types.rb +25 -16
  6. data/lib/teamcity/client/builds.rb +19 -15
  7. data/lib/teamcity/client/common.rb +0 -12
  8. data/lib/teamcity/client/projects.rb +21 -17
  9. data/lib/teamcity/client/vcs_roots.rb +11 -13
  10. data/lib/teamcity/configuration.rb +1 -5
  11. data/lib/teamcity/connection.rb +7 -7
  12. data/lib/teamcity/headers.rb +47 -0
  13. data/lib/teamcity/request.rb +2 -8
  14. data/lib/teamcity/version.rb +1 -1
  15. data/spec/cassettes/BuildTypes/DELETE/_delete_agent_requirement/should_delete_the_agent_requirement.yml +51 -6
  16. data/spec/cassettes/BuildTypes/DELETE/_delete_buildtype/should_delete_a_buildtype.yml +8 -6
  17. data/spec/cassettes/BuildTypes/DELETE/_delete_buildtype_parameter/should_delete_a_buildtype_parameter.yml +49 -6
  18. data/spec/cassettes/BuildTypes/GET/_buildtype/should_fetch_the_details_of_a_buildtype_by_id.yml +51 -11
  19. data/spec/cassettes/BuildTypes/GET/_buildtype/should_raise_an_error_if_the_buildtype_does_not_exist.yml +8 -6
  20. data/spec/cassettes/BuildTypes/GET/_buildtype_agent_requirements/should_fetch_the_build_configuration_agent_requirements_for_a_buildtype.yml +9 -7
  21. data/spec/cassettes/BuildTypes/GET/_buildtype_agent_requirements/should_return_an_array.yml +9 -7
  22. data/spec/cassettes/BuildTypes/GET/_buildtype_agent_requirements/should_return_nil_if_there_are_no_agent_requirements_defined.yml +9 -7
  23. data/spec/cassettes/BuildTypes/GET/_buildtype_artifact_dependencies/should_fetch_the_build_configuration_artifact_dependencies_for_a_buildtype.yml +9 -7
  24. data/spec/cassettes/BuildTypes/GET/_buildtype_artifact_dependencies/should_return_an_array.yml +9 -7
  25. data/spec/cassettes/BuildTypes/GET/_buildtype_artifact_dependencies/should_return_nil_if_there_are_no_artifact_dependencies_defined.yml +9 -7
  26. data/spec/cassettes/BuildTypes/GET/_buildtype_features/should_fetch_the_build_configuration_features_for_a_buildtype.yml +9 -7
  27. data/spec/cassettes/BuildTypes/GET/_buildtype_features/should_return_an_array.yml +9 -7
  28. data/spec/cassettes/BuildTypes/GET/_buildtype_features/should_return_nil_if_there_are_no_features_defined.yml +9 -7
  29. data/spec/cassettes/BuildTypes/GET/_buildtype_investigations/should_get_investigation_details.yml +11 -11
  30. data/spec/cassettes/BuildTypes/GET/_buildtype_investigations/should_return_nil_if_no_one_is_investigating.yml +9 -7
  31. data/spec/cassettes/BuildTypes/GET/_buildtype_parameters/should_fetch_the_build_configuration_parameters_for_a_buildtype.yml +9 -7
  32. data/spec/cassettes/BuildTypes/GET/_buildtype_parameters/should_return_an_array.yml +9 -7
  33. data/spec/cassettes/BuildTypes/GET/_buildtype_parameters/should_return_nil_if_there_are_no_parameters_defined.yml +9 -7
  34. data/spec/cassettes/BuildTypes/GET/_buildtype_settings/should_fetch_the_settings_for_a_given_buildtype.yml +51 -6
  35. data/spec/cassettes/BuildTypes/GET/_buildtype_settings/should_return_an_array.yml +51 -6
  36. data/spec/cassettes/BuildTypes/GET/_buildtype_snapshot_dependencies/should_fetch_the_build_configuration_snapshot_dependencies_for_a_buildtype.yml +9 -7
  37. data/spec/cassettes/BuildTypes/GET/_buildtype_snapshot_dependencies/should_return_an_array.yml +9 -7
  38. data/spec/cassettes/BuildTypes/GET/_buildtype_snapshot_dependencies/should_return_nil_if_there_are_no_snapshot_dependencies_defined.yml +9 -7
  39. data/spec/cassettes/BuildTypes/GET/_buildtype_state/should_fetch_the_state_of_the_buildtype.yml +89 -0
  40. data/spec/cassettes/BuildTypes/GET/_buildtype_steps/should_fetch_the_build_configuration_steps_for_a_buildtype.yml +10 -9
  41. data/spec/cassettes/BuildTypes/GET/_buildtype_steps/should_return_an_array.yml +9 -9
  42. data/spec/cassettes/BuildTypes/GET/_buildtype_steps/should_return_nil_if_there_are_no_steps_defined.yml +9 -7
  43. data/spec/cassettes/BuildTypes/GET/_buildtype_template/should_return_nil_if_the_buildtype_is_not_associated_with_a_template.yml +8 -6
  44. data/spec/cassettes/BuildTypes/GET/_buildtype_template/should_return_the_attributes_of_the_associated_template.yml +9 -8
  45. data/spec/cassettes/BuildTypes/GET/_buildtype_triggers/should_fetch_the_build_configuration_triggers_for_a_buildtype.yml +8 -6
  46. data/spec/cassettes/BuildTypes/GET/_buildtype_triggers/should_return_an_array.yml +8 -6
  47. data/spec/cassettes/BuildTypes/GET/_buildtype_triggers/should_return_nil_if_there_are_no_triggers_defined.yml +9 -7
  48. data/spec/cassettes/BuildTypes/GET/_buildtype_vcs_root_entries/should_fetch_the_build_configuration_vcs_root_entries_for_a_buildtype.yml +10 -8
  49. data/spec/cassettes/BuildTypes/GET/_buildtype_vcs_root_entries/should_return_an_array.yml +10 -8
  50. data/spec/cassettes/BuildTypes/GET/_buildtype_vcs_root_entries/should_return_nil_if_there_are_no_vcs_root_entries_defined.yml +9 -7
  51. data/spec/cassettes/BuildTypes/GET/_buildtypes/should_fetch_all_the_buildtypes.yml +9 -12
  52. data/spec/cassettes/BuildTypes/POST/_attach_vcs_root/should_attach_a_vcs_root_to_a_buildtype.yml +9 -9
  53. data/spec/cassettes/BuildTypes/POST/_create_agent_requirement/should_create_an_agent_requirement_for_a_buildtype.yml +10 -9
  54. data/spec/cassettes/BuildTypes/PUT/_set_build_step_field/should_disable_a_build_step.yml +14 -10
  55. data/spec/cassettes/BuildTypes/PUT/_set_build_step_field/should_enable_a_build_step.yml +18 -10
  56. data/spec/cassettes/BuildTypes/PUT/_set_buildtype_field/should_pause_a_project.yml +14 -10
  57. data/spec/cassettes/BuildTypes/PUT/_set_buildtype_field/should_set_a_projects_description.yml +15 -11
  58. data/spec/cassettes/BuildTypes/PUT/_set_buildtype_field/should_set_the_buildtype_name.yml +15 -11
  59. data/spec/cassettes/BuildTypes/PUT/_set_buildtype_parameter/should_set_a_buildtype_parameter.yml +15 -11
  60. data/spec/cassettes/Builds/DELETE/_unpin_build/should_unpin_a_build.yml +51 -6
  61. data/spec/cassettes/Builds/GET/_build/should_fetch_the_build_details.yml +53 -11
  62. data/spec/cassettes/Builds/GET/_build/should_raise_an_error_if_the_build_does_not_exist.yml +16 -13
  63. data/spec/cassettes/Builds/GET/_build_pinned_/should_return_false_when_a_build_is_not_pinned.yml +126 -0
  64. data/spec/cassettes/Builds/GET/_build_pinned_/should_return_true_when_a_build_is_pinned.yml +126 -0
  65. data/spec/cassettes/Builds/GET/_build_statistics/should_return_statistics_for_a_build.yml +50 -5
  66. data/spec/cassettes/Builds/GET/_build_tags/should_fetch_the_build_tags.yml +51 -6
  67. data/spec/cassettes/Builds/GET/_build_tags/should_return_an_empty_array_if_there_are_no_build_tags_defined_for_a_build.yml +89 -0
  68. data/spec/cassettes/Builds/GET/_builds/should_allow_you_to_filter_by_multiple_build_locators.yml +9 -7
  69. data/spec/cassettes/Builds/GET/_builds/should_allow_you_to_filter_results_by_build_locators.yml +9 -7
  70. data/spec/cassettes/Builds/GET/_builds/should_fetch_all_the_builds.yml +9 -7
  71. data/spec/cassettes/Builds/GET/{_build_statistics/should_return_an_empty_string_for_a_build_with_no_statistics.yml → _builds/should_return_an_empty_array_if_no_results_are_found.yml} +9 -7
  72. data/spec/cassettes/Builds/PUT/_pin_build/should_pin_a_build.yml +49 -6
  73. data/spec/cassettes/Projects/DELETE/_delete_project/should_delete_a_project.yml +17 -14
  74. data/spec/cassettes/Projects/DELETE/_delete_project_parameter/should_delete_a_project_parameter.yml +91 -6
  75. data/spec/cassettes/Projects/GET/_project/should_fetch_a_single_project_by_id.yml +10 -10
  76. data/spec/cassettes/Projects/GET/_project/should_raise_an_error_if_the_project_does_not_exist.yml +9 -7
  77. data/spec/cassettes/Projects/GET/_project_buildtypes/should_fetch_all_the_buildTypes_for_a_project.yml +9 -8
  78. data/spec/cassettes/Projects/GET/{_projects/should_return_nil_if_there_are_no_projects.yml → _project_buildtypes/should_return_nil_if_the_project_does_not_have_any_build_types.yml} +9 -7
  79. data/spec/cassettes/Projects/GET/_project_parameters/should_fetch_all_the_paramters_for_a_given_project.yml +9 -7
  80. data/spec/cassettes/Projects/GET/_project_parameters/should_return_nil_if_there_are_no_parameters_defined_for_a_project.yml +9 -7
  81. data/spec/cassettes/Projects/GET/_projects/should_fetch_projects.yml +9 -9
  82. data/spec/cassettes/Projects/POST/_copy_project/should_copy_a_project.yml +61 -15
  83. data/spec/cassettes/Projects/POST/_create_project/should_create_a_project.yml +9 -8
  84. data/spec/cassettes/Projects/PUT/_set_project_field/should_archive_a_project.yml +56 -10
  85. data/spec/cassettes/Projects/PUT/_set_project_field/should_set_a_projects_description.yml +56 -10
  86. data/spec/cassettes/Projects/PUT/_set_project_field/should_set_a_projects_name.yml +56 -10
  87. data/spec/cassettes/Projects/PUT/_set_project_parameter/should_set_a_project_parameter.yml +56 -10
  88. data/spec/cassettes/VCSRoots/GET/_vcs_root_details/should_fetch_the_vcs_root_details.yml +53 -6
  89. data/spec/cassettes/VCSRoots/GET/_vcs_roots/should_fetch_vcs_roots.yml +10 -7
  90. data/spec/cassettes/VCSRoots/POST/_create_vcs_root/should_create_a_vcs_root_that_is_shared_with_the_project_and_sub-projects.yml +90 -0
  91. data/spec/spec_helper.rb +1 -1
  92. data/spec/teamcity/api_spec.rb +0 -1
  93. data/spec/teamcity/client/builds_spec.rb +36 -56
  94. data/spec/teamcity/client/buildtypes_spec.rb +78 -42
  95. data/spec/teamcity/client/projects_spec.rb +41 -32
  96. data/spec/teamcity/client/vcs_roots_spec.rb +9 -29
  97. data/spec/teamcity/client_spec.rb +5 -1
  98. data/spec/teamcity/headers_spec.rb +43 -0
  99. data/spec/teamcity_spec.rb +1 -28
  100. data/teamcity-ruby-client.gemspec +1 -0
  101. metadata +21 -23
  102. data/spec/cassettes/BuildTypes/GET/_buildtype_template/should_raise_an_exception_if_the_response_is_not_due_to_a_template_not_assigned.yml +0 -50
  103. data/spec/cassettes/Builds/GET/_build_tags/should_return_nil_if_there_are_no_build_tags_defined_for_a_build.yml +0 -44
  104. data/spec/cassettes/Builds/GET/_builds/should_allow_you_to_search_by_locator.yml +0 -44
  105. data/spec/cassettes/Projects/GET/_project_buildtypes/should_return_nil_if_the_project_does_not_have_any_build_build_types.yml +0 -44
  106. data/spec/cassettes/Projects/PUT/_set_project_field/should_un-archive_a_project.yml +0 -50
  107. data/spec/cassettes/Projects/PUT/_set_project_parameter/should_set_a_project_parameter_with_a_boolean_value.yml +0 -40
  108. data/spec/cassettes/VCSRoots/POST/_create_vcs_root/should_create_a_shared_vcs_root.yml +0 -45
  109. data/spec/cassettes/VCSRoots/POST/_create_vcs_root/should_create_a_vcs_root_that_is_only_shared_within_a_project.yml +0 -48
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzU1YTc3MWEyYzhmZTVjMDRiMGI4MTBlMzg5NmNiODEwM2NmOWY5ZA==
4
+ YTE4MmFkNGIxMzQ3YTJlNmY4OTRkZGNmNGVkNzcwYmI0MjhiMzZlZQ==
5
5
  data.tar.gz: !binary |-
6
- YWE3NzczNzUxMmI5ZjJiODRiYjg5M2RjNzNkOTdjYzIzNzc5NzMyNQ==
6
+ MGRjMjFiMmE5NGJkZmIxNjUzZTczMjRiNzkwMDE5OGFmOGI4NDAxMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OThjYzE5Y2RmYzk2OWFiYjJhZmMzMGU5Zjk2NWQ1MGM2Zjg4ZjU1NTc2M2Ni
10
- ZDM0NzVjMDI2OWZjYWEwZjVmMDZkYTg2NmY0MjJkNGIyYmUyZmJiYTU3ODY4
11
- OTkwNDk5MzlmYzZiMzY0OWZhNzc5MjRjNWQ2MTk1Y2YyMjEzMGE=
9
+ Njc4OWRkZjRiMTE1NTkyYjY2YjEyNzZjYjZiZWU0Mzg5NmQwYTE0YzIwN2Y2
10
+ OTBjNDVjYTdmOTM3ZmM1NjRkM2ZiNzg4YTUwNGI3MDk4OGQ1MTQ0MzJkODJj
11
+ NmQ1NDA1YjViYTMyNDg1ZjVjNGEwNWZmNWNjNGNjYzkzMGM2MDQ=
12
12
  data.tar.gz: !binary |-
13
- NjJlZWZhNzkwZjk2YjZmNDUxNmEzZTQ3OWFlNjU1YjM0ZjY2MzgyYTM0NDQ5
14
- MTA0YmQyMDY3ZjcxODQxOTVkMzE0NDI0ODM5ZTg4YTU5ZmRkMDZiZTE0M2Iw
15
- N2UyNTkzZmQ2YTk4YzE5YWM5NTZkYTViZjliNzEyNGYxMWJhMzc=
13
+ NDlmMWZjNTJjMzc3YmJhZjM3ODE1NDA4MzdmYjkyYmJmYTgxOWJjZGVhNTlh
14
+ NjExOWI4YmQ5NDE1ZmIwOTA4MTcxMjhjNGViZWRhNzA1ZDRiZTQ1NDVmYjgy
15
+ ODFlNjBjMjdjMGU2OGE1YmRlZWUxNGVhYjA1YTlhMzhiMjExNWU=
data/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
+ ## 1.0.0 (Aug 26, 2013)
2
+
3
+ * Features:
4
+ * TeamCity 8 Support
5
+ * Added ```build_pinned?``` (Provides the ability to ask if a build is pinned)
6
+ * If using TeamCity8 any call that is setting a value will now return that value instead of nil
7
+
8
+ * API Changes:
9
+ * ```create_vcs_root``` method signature has been changed from using Ordinal Params to using Hash Params
10
+ * Removed the ability to set the format when configuring the client (Each method will now state what format it is sending and receiving, see the source for more info)
11
+
12
+ * Doc Changes:
13
+ * The API docs were updated to reflect the return values now returned when using TeamCity 8
14
+
1
15
  ## 0.4.0 (Jun 15, 2013)
2
16
 
3
- * Added ```pin_build``` and ```unpin_build``` (Provides the ability to pin and unbuild a build respectively)
17
+ * Added ```pin_build``` and ```unpin_build``` (Provides the ability to pin and unpin a build respectively)
4
18
  * Added ```build_statistics``` (Provides the ability to fetch build [statistics](http://confluence.jetbrains.com/display/TCD8/Custom+Chart#CustomChart-listOfDefaultStatisticValues))
5
19
  * Added ```buildtype_investigations``` (Provides the ability to fetch build investigation details)
6
20
 
data/README.md CHANGED
@@ -19,19 +19,21 @@ Or install it yourself as:
19
19
 
20
20
  ## API Usage Examples
21
21
 
22
- * Tested on TeamCity 7.0 and higher
22
+ * Tested on TeamCity 7.X and 8.X
23
23
  * Most of the api calls return either an array of Hashie::Mash objects or a single Hashie::Mash object which allows you to send messages to retreive an attribute easily.
24
24
  * See [api docs](http://rubydoc.info/gems/teamcity-ruby-client/TeamCity/Client) or [specs](spec/teamcity/client) for additional examples and usage
25
25
 
26
26
  ### Configuration
27
27
 
28
28
  * See [configuration](lib/teamcity/configuration.rb) source or api doc for more configuration options
29
+ * You may use v7 of the TeamCity api by adding '7.0' to the endpoint configuration (This would be similar to using latest on a TeamCity 7 server)
29
30
 
30
31
  ```ruby
31
32
  require 'teamcity'
32
33
 
33
34
  # This only needs to be set once per Ruby execution.
34
35
  # You may use guestAuth instead of httpAuth and omit the use of http_user and http_password
36
+ # This is using the latest version of the api
35
37
  TeamCity.configure do |config|
36
38
  config.endpoint = 'http://my-teamcity-server:8111/httpAuth/app/rest'
37
39
  config.http_user = 'teamcity-user'
@@ -121,7 +123,7 @@ puts Teamcity.vcs_roots
121
123
  puts TeamCity.vcs_root_details(1)
122
124
 
123
125
  # Create VCS Root for a project
124
- TeamCity.create_vcs_root('my-git-vcs-root', 'git', :projectLocator => 'project2') do |properties|
126
+ TeamCity.create_vcs_root(vcs_name: 'my-git-vcs-root', vcs_type: 'git', :project_id => 'project2') do |properties|
125
127
  properties['branch'] = 'master'
126
128
  properties['url'] = 'git@github.com:jperry/teamcity-ruby-client.git'
127
129
  properties['authMethod'] = 'PRIVATE_KEY_DEFAULT'
data/lib/teamcity.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative 'teamcity/configuration'
2
2
  require_relative 'teamcity/client'
3
+ require_relative 'teamcity/headers'
3
4
 
4
5
  module TeamCity
5
6
  extend Configuration
@@ -26,11 +26,15 @@ module TeamCity
26
26
  get("buildTypes/#{locator(options)}")
27
27
  end
28
28
 
29
- # TODO: File jetbrains ticket, this call doesn't work
30
- #def buildtype_state(options={})
31
- # assert_options(options)
32
- # get("buildTypes/#{locator(options)}/paused")
33
- #end
29
+ # Get whether the build is paused or not
30
+ #
31
+ # @param options [Hash] option keys, :id => buildtype_id
32
+ # @return [String] 'true' or 'false' on whether the build is paused
33
+ def buildtype_state(options={})
34
+ assert_options(options)
35
+ path = "buildTypes/#{locator(options)}/paused"
36
+ get(path, :accept => :text, :content_type => :text)
37
+ end
34
38
 
35
39
  # Get build configuration settings
36
40
  #
@@ -120,10 +124,12 @@ module TeamCity
120
124
  # @param buildtype_id [String] the buildtype id
121
125
  # @param parameter_name [String] name of the parameter to set
122
126
  # @param parameter_value [String] value of the parameter
123
- # @return [nil]
127
+ # @return parameter_value [String] that was set
124
128
  def set_buildtype_parameter(buildtype_id, parameter_name, parameter_value)
125
129
  path = "buildTypes/#{buildtype_id}/parameters/#{parameter_name}"
126
- put_text_request(path, parameter_value)
130
+ put(path, :accept => :text, :content_type => :text) do |req|
131
+ req.body = parameter_value
132
+ end
127
133
  end
128
134
 
129
135
  # Delete a buildtype parameter
@@ -132,10 +138,8 @@ module TeamCity
132
138
  # @param parameter_name [String] name of the parameter to delete
133
139
  # @return [nil]
134
140
  def delete_buildtype_parameter(buildtype_id, parameter_name)
135
- delete("buildTypes/#{buildtype_id}/parameters/#{parameter_name}") do |req|
136
- # only accepts text/plain
137
- req.headers['Accept'] = 'text/plain'
138
- end
141
+ path = "buildTypes/#{buildtype_id}/parameters/#{parameter_name}"
142
+ delete(path, :accept => :text, :content_type => :text)
139
143
  end
140
144
 
141
145
  # Create a buildtype agent requirement (Create)
@@ -144,7 +148,7 @@ module TeamCity
144
148
  # @param parameter_name [String] name of the parameter to set
145
149
  # @param parameter_value [String] value of the parameter
146
150
  # @param condition [String] the condition for which to check against
147
- # @return [nil]
151
+ # @return [Hashie::Mash]
148
152
  #
149
153
  # @example Create a condition where a system property equals something
150
154
  # TeamCity.create_agent_requirement('bt1', 'system.os.name', 'Linux', 'equals')
@@ -158,8 +162,8 @@ module TeamCity
158
162
  p.property(:name => 'property-value', :value => parameter_value)
159
163
  end
160
164
  end
161
- post("buildTypes/#{buildtype_id}/agent-requirements") do |req|
162
- req.headers['Content-Type'] = 'application/xml'
165
+ path = "buildTypes/#{buildtype_id}/agent-requirements"
166
+ post(path, :accept => :json, :content_type => :xml) do |req|
163
167
  req.body = builder.target!
164
168
  end
165
169
  end
@@ -185,9 +189,12 @@ module TeamCity
185
189
  # @param buidltype_id [String] the buildtype id
186
190
  # @param field_name [String] the field name
187
191
  # @param field_value [String] the value to set the field to
192
+ # @return field_value [String] value that was set
188
193
  def set_buildtype_field(buildtype_id, field_name, field_value)
189
194
  path = "buildTypes/#{buildtype_id}/#{field_name}"
190
- put_text_request(path, field_value)
195
+ put(path, :accept => :text, :content_type => :text) do |req|
196
+ req.body = field_value
197
+ end
191
198
  end
192
199
 
193
200
  # Delete buildtype (build configuration)
@@ -207,7 +214,9 @@ module TeamCity
207
214
  # @return [nil]
208
215
  def set_build_step_field(buildtype_id, step_id, field_name, field_value)
209
216
  path = "buildTypes/#{buildtype_id}/steps/#{step_id}/#{field_name}"
210
- put_text_request(path, field_value)
217
+ put(path, :accept => :text, :content_type => :text) do |req|
218
+ req.body = field_value
219
+ end
211
220
  end
212
221
  end
213
222
  end
@@ -8,11 +8,11 @@ module TeamCity
8
8
  # List of builds
9
9
  #
10
10
  # @param options [Hash] list of build locators to filter build results on
11
- # @return [Array<Hashie::Mash>, nil] of builds or nil if no builds exist
11
+ # @return [Array<Hashie::Mash>] of builds (empty array if no builds exist)
12
12
  def builds(options={})
13
13
  url_params = options.empty? ? '' : "?locator=#{locator(options)}"
14
14
  response = get("builds#{url_params}")
15
- response['build']
15
+ response.build
16
16
  end
17
17
 
18
18
  # Get build details
@@ -27,30 +27,31 @@ module TeamCity
27
27
  # Get the build tags
28
28
  #
29
29
  # @param options [Hash] option keys, :id => build_id
30
- # @return [Array<Hashie::Mash>, nil] nil if build has not tags
30
+ # @return [Array<Hashie::Mash>] or empty array if no tags exist
31
31
  def build_tags(options={})
32
32
  assert_options(options)
33
33
  response = get("builds/#{locator(options)}/tags")
34
- response['tag']
34
+ response.fetch(:tag)
35
35
  end
36
36
 
37
37
  # Get build statistics
38
38
  #
39
39
  # @param build_id [String]
40
- # @return [Array<Hashie::Mash>, nil] returns nil if there are no statistics
40
+ # @return [Array<Hashie::Mash>]
41
41
  def build_statistics(build_id)
42
42
  response = get("builds/#{build_id}/statistics")
43
43
  response['property']
44
44
  end
45
45
 
46
- # TODO: Will need to create a Faraday middleware for this
47
- # since the response returns a string not a json object
48
- #def build_pinned?(id)
49
- # path = "builds/#{id}/pin"
50
- # get(path) do |req|
51
- # req.headers['Accept'] = 'text/plain'
52
- # end
53
- #end
46
+ # Tells you whether or not a build is pinned
47
+ #
48
+ # @param id [String] build to check if it is pinned
49
+ # @return [Boolean] whether the build is pinned or not
50
+ def build_pinned?(id)
51
+ path = "builds/#{id}/pin"
52
+ response = get(path, :accept => :text, :content_type => :text)
53
+ response == 'true'
54
+ end
54
55
 
55
56
  # HTTP PUT
56
57
 
@@ -61,7 +62,9 @@ module TeamCity
61
62
  # @return [nil]
62
63
  def pin_build(id, comment='')
63
64
  path = "builds/#{id}/pin"
64
- put_text_request(path, comment)
65
+ put(path, :accept => :text, :content_type => :text) do |req|
66
+ req.body = comment
67
+ end
65
68
  end
66
69
 
67
70
  # HTTP DELETE
@@ -71,7 +74,8 @@ module TeamCity
71
74
  # @param id [String] build to unpin
72
75
  # @return [nil]
73
76
  def unpin_build(id)
74
- delete("builds/#{id}/pin")
77
+ path = "builds/#{id}/pin"
78
+ delete(path, :content_type => :text)
75
79
  end
76
80
  end
77
81
  end
@@ -18,18 +18,6 @@ module TeamCity
18
18
  locators << "#{key}:#{value}"
19
19
  end.join(',')
20
20
  end
21
-
22
- # Put request helper where the body is text
23
- #
24
- # @param path [String] request path
25
- # @param body [String] body contents of the request
26
- # @return [nil]
27
- def put_text_request(path, body)
28
- put(path) do |req|
29
- req.headers['Content-Type'] = 'text/plain'
30
- req.body = body
31
- end
32
- end
33
21
  end
34
22
  end
35
23
  end
@@ -24,7 +24,7 @@ module TeamCity
24
24
  # List of Build Configurations of a project
25
25
  #
26
26
  # @param (see #project)
27
- # @return [Array<Hashie::Mash>, nil] of build types or nil if no build types exist
27
+ # @return [Array<Hashie::Mash> of build types (an empty array will be returne if none exist)
28
28
  def project_buildtypes(options={})
29
29
  assert_options(options)
30
30
  response = get("projects/#{locator(options)}/buildTypes")
@@ -34,7 +34,7 @@ module TeamCity
34
34
  # List of parameters defined on a project
35
35
  #
36
36
  # @param (see #project)
37
- # @return [Array<Hashie::Mash>, nil] of parameters or nil if no parameters are defined
37
+ # @return [Array<Hashie::Mash>] of parameters (empty if none are defined)
38
38
  def project_parameters(options={})
39
39
  assert_options(options)
40
40
  response = get("projects/#{locator(options)}/parameters")
@@ -46,8 +46,7 @@ module TeamCity
46
46
  # @param name [String] Name of the project
47
47
  # @return [Hashie::Mash] project details
48
48
  def create_project(name)
49
- post("projects") do |req|
50
- req.headers['Content-Type'] = 'text/plain'
49
+ post("projects", :content_type => :text) do |req|
51
50
  req.body = name
52
51
  end
53
52
  end
@@ -58,17 +57,18 @@ module TeamCity
58
57
  # @param target_project_name [String] name of the project you want to create
59
58
  # @param options [Hash] copy project options
60
59
  # @option options [Boolean] :copyAllAssociatedSettings copy all associated settings
61
- # @options options[Boolean] :shareVCSRoots when true the vcs roots will be shared, otherwise they will be copied
60
+ # @options options [String] :parentProject used to define the parent project to create this project under (root will be use by default)
61
+ # @options options [String] :id to use for the new project
62
62
  # @return [Hashie::Mash] project details
63
63
  def copy_project(source_project_id, target_project_name, options={})
64
64
  attributes = {
65
- :name => target_project_name,
66
- :sourceProjectLocator => "id:#{source_project_id}",
65
+ :name => target_project_name
67
66
  }
68
- post("projects") do |req|
69
- req.headers['Content-Type'] = 'application/xml'
70
- builder = Builder::XmlMarkup.new
71
- builder.newProjectDescription(options.merge(attributes))
67
+ builder = Builder::XmlMarkup.new
68
+ builder.tag!(:newProjectDescription ,options.merge(attributes)) do |node|
69
+ node.tag!(:sourceProject, locator: source_project_id)
70
+ end
71
+ post("projects", :content_type => :xml) do |req|
72
72
  req.body = builder.target!
73
73
  end
74
74
  end
@@ -87,10 +87,8 @@ module TeamCity
87
87
  # @param parameter_name [String] name of the parameter to delete
88
88
  # @return [nil]
89
89
  def delete_project_parameter(project_id, parameter_name)
90
- delete("projects/#{project_id}/parameters/#{parameter_name}") do |req|
91
- # only accepts text/plain
92
- req.headers['Accept'] = 'text/plain'
93
- end
90
+ path = "projects/#{project_id}/parameters/#{parameter_name}"
91
+ delete(path, :accept => :text)
94
92
  end
95
93
 
96
94
  # Set a project parameter (Create or Update)
@@ -99,9 +97,12 @@ module TeamCity
99
97
  # @param project_id [String] the project id
100
98
  # @param parameter_name [String] name of the parameter to set
101
99
  # @param parameter_value [String] value of the parameter
100
+ # @return [String] parameter_value that was set
102
101
  def set_project_parameter(project_id, parameter_name, parameter_value)
103
102
  path = "projects/#{project_id}/parameters/#{parameter_name}"
104
- put_text_request(path, parameter_value)
103
+ put(path, :content_type => :text, :accept => :text) do |req|
104
+ req.body = parameter_value
105
+ end
105
106
  end
106
107
 
107
108
  # Set a project field
@@ -116,9 +117,12 @@ module TeamCity
116
117
  # @param project_id [String] the project id
117
118
  # @param field_name [String] the field name: 'name', 'description', 'archived'
118
119
  # @param field_value [String] the value to set the field to
120
+ # @return [String] project_field_value that was set
119
121
  def set_project_field(project_id, field_name, field_value)
120
122
  path = "projects/#{project_id}/#{field_name}"
121
- put_text_request(path, field_value)
123
+ put(path, :content_type => :text, :accept => :text) do |req|
124
+ req.body = field_value
125
+ end
122
126
  end
123
127
  end
124
128
  end
@@ -20,28 +20,27 @@ module TeamCity
20
20
 
21
21
  # Create VCS Root
22
22
  #
23
- # @param vcs_name [String] Name of the vcs root
24
- # @param vcs_type [String] Type of VCS: 'git', 'perforce', etc
25
- # @param options [Hash] VCS root options
26
- # @option options [String] :projectLocator the project id (not required if :shared => true)
27
- # @option options [Boolean] :shared whether the vcs root is shared across projects
23
+ # @option options [String] :vcs_name Name of the vcs root
24
+ # @option options [String] :vcs_type Type of VCS: 'git', 'perforce', etc
25
+ # @option options [String] :project_id to create the vcs root under
28
26
  # @yield [Hash] properties to set on the vcs root, view the page source of the vcs root page for the id and value of a property
29
27
  # @return [Hashie::Mash] vcs root object that was created
30
28
  #
31
- # @example Create a Git VCS Root that pulls from master that is only shared within a project and uses the default private key
32
- # TeamCity.create_vcs_root('my-git-vcs-root', 'git', :projectLocator => 'project2') do |properties|
29
+ # @example Create a Git VCS Root that pulls from master that is only shared with it's project and sub-projecdts and uses the default private key
30
+ # TeamCity.create_vcs_root(:vcs_name => 'my-git-vcs-root', :vcs_type => 'git', :project_id => 'project2') do |properties|
33
31
  # properties['branch'] = 'master'
34
32
  # properties['url'] = 'git@github.com:jperry/teamcity-ruby-client.git'
35
33
  # properties['authMethod'] = 'PRIVATE_KEY_DEFAULT'
36
34
  # properties['ignoreKnownHosts'] = true
37
35
  # end
38
- def create_vcs_root(vcs_name, vcs_type, options = {}, &block)
36
+ def create_vcs_root(options = {}, &block)
39
37
  attributes = {
40
- :name => vcs_name,
41
- :vcsName => "jetbrains.#{vcs_type}"
38
+ :name => options.fetch(:vcs_name),
39
+ :vcsName => "jetbrains.#{options.fetch(:vcs_type)}",
40
+ :projectLocator => options.fetch(:project_id)
42
41
  }
43
42
  builder = Builder::XmlMarkup.new
44
- builder.tag!('vcs-root'.to_sym, options.merge(attributes)) do |node|
43
+ builder.tag!('vcs-root'.to_sym, attributes) do |node|
45
44
  node.properties do |p|
46
45
  if block_given?
47
46
  properties = {}
@@ -52,8 +51,7 @@ module TeamCity
52
51
  end
53
52
  end
54
53
  end
55
- post("vcs-roots") do |req|
56
- req.headers['Content-Type'] = 'application/xml'
54
+ post("vcs-roots", :content_type => :xml) do |req|
57
55
  req.body = builder.target!
58
56
  end
59
57
  end
@@ -7,16 +7,13 @@ module TeamCity
7
7
  :adapter,
8
8
  :endpoint,
9
9
  :user_agent,
10
- :format,
11
10
  :http_user,
12
11
  :http_password
13
12
  ].freeze
14
13
 
15
- VALID_FORMATS = [:json].freeze
16
-
17
14
  DEFAULT_ADAPTER = Faraday.default_adapter
18
15
 
19
- DEFAULT_ENDPOINT = 'http://teamcity:8111/httpAuth/app/rest/7.0/'.freeze
16
+ DEFAULT_ENDPOINT = 'http://teamcity:8111/httpAuth/app/rest/'.freeze
20
17
 
21
18
  DEFAULT_USER_AGENT = "TeamCity Ruby Client #{TeamCity::VERSION}".freeze
22
19
 
@@ -47,7 +44,6 @@ module TeamCity
47
44
  self.adapter = DEFAULT_ADAPTER
48
45
  self.endpoint = DEFAULT_ENDPOINT
49
46
  self.user_agent = DEFAULT_USER_AGENT
50
- self.format = DEFAULT_FORMAT
51
47
  self.http_user = DEFAULT_HTTP_USER
52
48
  self.http_password = DEFAULT_HTTP_PASSWORD
53
49
  end
@@ -6,19 +6,19 @@ module TeamCity
6
6
  module Connection
7
7
  private
8
8
 
9
- def connection
10
- options = {
11
- :headers => {'Accept' => "application/#{format}; charset=utf-8", 'User-Agent' => user_agent},
9
+ def connection(options={})
10
+ faraday_options = {
11
+ :headers => {
12
+ 'User-Agent' => user_agent
13
+ }.merge((headers = Headers.build(options)).to_hash),
12
14
  :ssl => {:verify => false},
13
15
  :url => endpoint
14
16
  }
15
17
 
16
- Faraday::Connection.new(options) do |connection|
18
+ Faraday::Connection.new(faraday_options) do |connection|
17
19
  connection.use Faraday::Request::UrlEncoded
18
20
  connection.use FaradayMiddleware::Mashify
19
- case format.to_s.downcase
20
- when 'json' then connection.use FaradayMiddleware::ParseJson
21
- end
21
+ connection.use FaradayMiddleware::ParseJson if headers.accept =~ /json/
22
22
  connection.use FaradayMiddleware::NullResponseBody
23
23
  connection.adapter(adapter)
24
24
  connection.basic_auth(http_user, http_password)