teamcity-ruby-client 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)