v2gpti 1.1.9 → 1.2.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/bin/git-deliver +1 -1
  3. data/bin/git-finish +1 -1
  4. data/bin/git-newbug +1 -1
  5. data/bin/git-newfeature +1 -1
  6. data/bin/git-qa +1 -1
  7. data/bin/git-release +1 -1
  8. data/bin/git-report +1 -1
  9. data/bin/git-start +1 -1
  10. data/bin/git-uat +1 -1
  11. data/config_template +16 -0
  12. data/lib/git-pivotal-tracker-integration/command/base.rb +235 -322
  13. data/lib/git-pivotal-tracker-integration/command/configuration.rb +183 -109
  14. data/lib/git-pivotal-tracker-integration/command/deliver.rb +145 -200
  15. data/lib/git-pivotal-tracker-integration/command/finish.rb +70 -63
  16. data/lib/git-pivotal-tracker-integration/command/newbug.rb +36 -39
  17. data/lib/git-pivotal-tracker-integration/command/newfeature.rb +43 -42
  18. data/lib/git-pivotal-tracker-integration/command/release.rb +171 -203
  19. data/lib/git-pivotal-tracker-integration/command/report.rb +33 -36
  20. data/lib/git-pivotal-tracker-integration/command/start.rb +74 -78
  21. data/lib/git-pivotal-tracker-integration/util/git.rb +202 -204
  22. data/lib/git-pivotal-tracker-integration/util/shell.rb +19 -16
  23. data/lib/git-pivotal-tracker-integration/util/story.rb +155 -177
  24. data/lib/git-pivotal-tracker-integration/version-update/gradle.rb +44 -40
  25. data/lib/git-pivotal-tracker-integration.rb +44 -0
  26. data/spec/git-pivotal-tracker-integration/command/configuration_spec.rb +1 -2
  27. data/spec/git-pivotal-tracker-integration/command/finish_spec.rb +1 -1
  28. data/spec/git-pivotal-tracker-integration/command/release_spec.rb +1 -1
  29. data/spec/git-pivotal-tracker-integration/command/start_spec.rb +1 -1
  30. data/spec/git-pivotal-tracker-integration/util/story_spec.rb +21 -32
  31. data/tracker_api/lib/tracker_api/client.rb +241 -0
  32. data/tracker_api/lib/tracker_api/endpoints/activity.rb +38 -0
  33. data/tracker_api/lib/tracker_api/endpoints/comments.rb +27 -0
  34. data/tracker_api/lib/tracker_api/endpoints/epic.rb +17 -0
  35. data/tracker_api/lib/tracker_api/endpoints/epics.rb +20 -0
  36. data/tracker_api/lib/tracker_api/endpoints/file_attachment.rb +18 -0
  37. data/tracker_api/lib/tracker_api/endpoints/iterations.rb +20 -0
  38. data/tracker_api/lib/tracker_api/endpoints/me.rb +17 -0
  39. data/tracker_api/lib/tracker_api/endpoints/memberships.rb +20 -0
  40. data/tracker_api/lib/tracker_api/endpoints/notifications.rb +20 -0
  41. data/tracker_api/lib/tracker_api/endpoints/project.rb +17 -0
  42. data/tracker_api/lib/tracker_api/endpoints/projects.rb +18 -0
  43. data/tracker_api/lib/tracker_api/endpoints/stories.rb +20 -0
  44. data/tracker_api/lib/tracker_api/endpoints/story.rb +37 -0
  45. data/tracker_api/lib/tracker_api/endpoints/tasks.rb +20 -0
  46. data/tracker_api/lib/tracker_api/error.rb +18 -0
  47. data/tracker_api/lib/tracker_api/logger.rb +31 -0
  48. data/tracker_api/lib/tracker_api/resources/account.rb +18 -0
  49. data/tracker_api/lib/tracker_api/resources/activity.rb +24 -0
  50. data/tracker_api/lib/tracker_api/resources/base.rb +71 -0
  51. data/tracker_api/lib/tracker_api/resources/change.rb +15 -0
  52. data/tracker_api/lib/tracker_api/resources/comment.rb +20 -0
  53. data/tracker_api/lib/tracker_api/resources/epic.rb +17 -0
  54. data/tracker_api/lib/tracker_api/resources/file_attachment.rb +23 -0
  55. data/tracker_api/lib/tracker_api/resources/iteration.rb +24 -0
  56. data/tracker_api/lib/tracker_api/resources/label.rb +14 -0
  57. data/tracker_api/lib/tracker_api/resources/me.rb +21 -0
  58. data/tracker_api/lib/tracker_api/resources/membership_summary.rb +15 -0
  59. data/tracker_api/lib/tracker_api/resources/notification.rb +26 -0
  60. data/tracker_api/lib/tracker_api/resources/person.rb +14 -0
  61. data/tracker_api/lib/tracker_api/resources/primary_resource.rb +13 -0
  62. data/tracker_api/lib/tracker_api/resources/project.rb +131 -0
  63. data/tracker_api/lib/tracker_api/resources/project_membership.rb +16 -0
  64. data/tracker_api/lib/tracker_api/resources/story.rb +102 -0
  65. data/tracker_api/lib/tracker_api/resources/task.rb +16 -0
  66. data/tracker_api/lib/tracker_api/resources/time_zone.rb +13 -0
  67. data/tracker_api/lib/tracker_api/version.rb +3 -0
  68. data/tracker_api/lib/tracker_api.rb +60 -0
  69. metadata +202 -53
  70. data/lib/git-pivotal-tracker-integration/command/command.rb +0 -20
  71. data/lib/git-pivotal-tracker-integration/util/util.rb +0 -20
  72. data/lib/git-pivotal-tracker-integration/version-update/version_update.rb +0 -20
  73. data/lib/git_pivotal_tracker_integration.rb +0 -18
@@ -0,0 +1,20 @@
1
+ module TrackerApi
2
+ module Endpoints
3
+ class Tasks
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def get(project_id, story_id, params={})
11
+ data = client.paginate("/projects/#{project_id}/stories/#{story_id}/tasks", params: params)
12
+ raise TrackerApi::Errors::UnexpectedData, 'Array of tasks expected' unless data.is_a? Array
13
+
14
+ data.map do |task|
15
+ Resources::Task.new({ story_id: story_id }.merge(task))
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module TrackerApi
2
+ class Error < StandardError
3
+ attr_reader :wrapped_exception, :response
4
+
5
+ def initialize(wrapped_exception)
6
+ @wrapped_exception = wrapped_exception
7
+ @response = wrapped_exception.response
8
+ message = if wrapped_exception.is_a?(Faraday::Error::ParsingError)
9
+ wrapped_exception.message
10
+ elsif wrapped_exception.is_a?(Faraday::Error::ClientError)
11
+ wrapped_exception.response.inspect
12
+ else
13
+ wrapped_exception.instance_variable_get(:@wrapped_exception).inspect
14
+ end
15
+ super(message)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module TrackerApi
2
+ class Logger < Faraday::Response::Middleware
3
+ extend Forwardable
4
+
5
+ def initialize(app, logger = nil)
6
+ super(app)
7
+ @logger = logger || ::Logger.new(STDOUT)
8
+ end
9
+
10
+ def_delegators :@logger, :debug, :info, :warn, :error, :fatal
11
+
12
+ def call(env)
13
+ info("#{env[:method]} => #{env[:url].to_s}")
14
+ debug('request') { dump_headers env[:request_headers] }
15
+ debug('request.body') { env[:body] }
16
+ super
17
+ end
18
+
19
+ def on_complete(env)
20
+ info("#{env[:status]} <= #{env[:url].to_s}")
21
+ debug('response') { dump_headers env[:response_headers] }
22
+ debug('response.body') { env[:body] }
23
+ end
24
+
25
+ private
26
+
27
+ def dump_headers(headers)
28
+ headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Account
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :created_at, DateTime
8
+ attribute :status, String
9
+ attribute :kind, String
10
+ attribute :name, String
11
+ attribute :updated_at, DateTime
12
+ attribute :url, String
13
+ attribute :plan, String
14
+ attribute :days_left, Integer
15
+ attribute :over_the_limit, Boolean
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Activity
4
+ include Virtus.model
5
+
6
+ attribute :client
7
+
8
+ attribute :kind, String
9
+ attribute :guid, String
10
+ attribute :project_version, Integer
11
+ attribute :message, String
12
+ attribute :highlight, String
13
+ attribute :changes, Array[TrackerApi::Resources::Change]
14
+ attribute :primary_resources, Array[TrackerApi::Resources::PrimaryResource]
15
+ attribute :project, TrackerApi::Resources::Project
16
+ attribute :performed_by, TrackerApi::Resources::Person
17
+ attribute :occurred_at, DateTime
18
+
19
+ def project=(data)
20
+ super.client = client
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,71 @@
1
+ require 'virtus'
2
+ require 'active_support/concern'
3
+ require 'active_model'
4
+
5
+ module TrackerApi
6
+ module Resources
7
+ module Base
8
+ extend ActiveSupport::Concern
9
+
10
+ include ActiveModel::Model
11
+ include ActiveModel::Dirty
12
+
13
+ included do
14
+ include Virtus.model
15
+ include OverrideAttributes
16
+
17
+ attribute :id, Integer
18
+
19
+ def initialize(attrs)
20
+ super
21
+
22
+ # always reset dirty tracking on initialize
23
+ clear_changes_information
24
+ end
25
+
26
+ private
27
+
28
+ # @return [Hash] key value pairs for just the changed attributes with their new values.
29
+ def just_changes
30
+ # @see changes in ActiveModel::Dirty in active_model/dirty.rb
31
+ # { attr => [original value, new value] }
32
+ changes.inject({}) do |h, (k, v)|
33
+ h[k] = v[1]; h;
34
+ end
35
+ end
36
+ end
37
+
38
+ module OverrideAttributes
39
+ extend ActiveSupport::Concern
40
+
41
+ module ClassMethods
42
+ def attribute(name, type, options = {})
43
+ define_attribute_methods name
44
+
45
+ attribute = super
46
+ create_writer_with_dirty_tracking(name)
47
+ attribute
48
+ end
49
+
50
+ private
51
+
52
+ def create_writer_with_dirty_tracking(name)
53
+ method_str = <<-RUBY
54
+ def #{name}=(value)
55
+ prev_value = #{name}
56
+ new_value = value
57
+ if prev_value != new_value
58
+ #{name}_will_change!
59
+ new_value = super(value)
60
+ end
61
+ new_value
62
+ end
63
+ RUBY
64
+
65
+ class_eval method_str, __FILE__, __LINE__ + 1
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,15 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Change
4
+ include Virtus.model
5
+
6
+ attribute :change_type, String
7
+ attribute :id, Integer
8
+ attribute :kind, String
9
+ attribute :name, String
10
+ attribute :new_values, Hash
11
+ attribute :original_values, Hash
12
+ attribute :story_type, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Comment
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :story_id, Integer
8
+ attribute :epic_id, Integer
9
+ attribute :text, String
10
+ attribute :person_id, Integer
11
+ attribute :created_at, DateTime
12
+ attribute :updated_at, DateTime
13
+ attribute :file_attachment_ids, Array[Integer]
14
+ attribute :google_attachment_ids, Array[Integer]
15
+ attribute :commit_identifier, String
16
+ attribute :commit_type, String
17
+ attribute :kind, String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Epic
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :created_at, DateTime
8
+ attribute :description, String
9
+ attribute :kind, String
10
+ attribute :label, TrackerApi::Resources::Label
11
+ attribute :name, String
12
+ attribute :project_id, Integer
13
+ attribute :updated_at, DateTime
14
+ attribute :url, String
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class FileAttachment
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :filename, String
8
+ attribute :created_at, DateTime
9
+ attribute :uploader_id, Integer
10
+ attribute :thumbnailable, Boolean
11
+ attribute :height, Integer
12
+ attribute :width, Integer
13
+ attribute :size, Integer
14
+ attribute :download_url, String
15
+ attribute :content_type, String
16
+ attribute :uploaded, Boolean
17
+ attribute :big_url, String
18
+ attribute :thumbnail_url, String
19
+ attribute :kind, String
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Iteration
4
+ include Virtus.model
5
+
6
+ attribute :client
7
+
8
+ attribute :finish, DateTime
9
+ attribute :kind, String
10
+ attribute :length, Integer
11
+ attribute :number, Integer
12
+ attribute :planned, Boolean
13
+ attribute :project_id, Integer
14
+ attribute :start, DateTime
15
+ attribute :stories, [TrackerApi::Resources::Story]
16
+ attribute :story_ids, [Integer]
17
+ attribute :team_strength, Float
18
+
19
+ def stories=(data)
20
+ super.each { |s| s.client = client }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Label
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :created_at, DateTime
8
+ attribute :kind, String
9
+ attribute :name, String
10
+ attribute :project_id, Integer
11
+ attribute :updated_at, DateTime
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Me
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :name, String
8
+ attribute :initials, String
9
+ attribute :username, String
10
+ attribute :time_zone, TrackerApi::Resources::TimeZone
11
+ attribute :api_token, String
12
+ attribute :has_google_identity, Boolean
13
+ attribute :project_ids, Array[Integer]
14
+ attribute :projects, [TrackerApi::Resources::MembershipSummary]
15
+ attribute :workspace_ids, Array[Integer]
16
+ attribute :email, String
17
+ attribute :receives_in_app_notifications, Boolean
18
+ attribute :kind, String
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class MembershipSummary
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :kind, String
8
+ attribute :last_viewed_at, DateTime
9
+ attribute :project_color, String
10
+ attribute :project_id, Integer
11
+ attribute :project_name, String
12
+ attribute :role, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Notification
4
+ include Virtus.model
5
+
6
+ attribute :client
7
+
8
+ attribute :id, Integer
9
+ attribute :message, String
10
+ attribute :kind, String
11
+ attribute :project, TrackerApi::Resources::Project
12
+ attribute :story, TrackerApi::Resources::Story
13
+ attribute :performer, TrackerApi::Resources::Person
14
+ attribute :created_at, DateTime
15
+ attribute :updated_at, DateTime
16
+
17
+ def project=(data)
18
+ super.client = client
19
+ end
20
+
21
+ def story=(data)
22
+ super.client = client
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Person
4
+ include Virtus.model
5
+
6
+ attribute :kind, String
7
+ attribute :id, Integer
8
+ attribute :name, String
9
+ attribute :email, String
10
+ attribute :initials, String
11
+ attribute :username, String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class PrimaryResource
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :kind, String
8
+ attribute :name, String
9
+ attribute :story_type, String
10
+ attribute :url, String
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,131 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Project
4
+ include Virtus.model
5
+
6
+ attribute :client
7
+
8
+ attribute :account, TrackerApi::Resources::Account
9
+ attribute :account_id, Integer
10
+ attribute :atom_enabled, Boolean
11
+ attribute :bugs_and_chores_are_estimatable, Boolean
12
+ attribute :created_at, DateTime
13
+ attribute :current_iteration_number, Integer
14
+ attribute :current_velocity, Integer
15
+ attribute :description, String
16
+ attribute :enable_following, Boolean
17
+ attribute :enable_incoming_emails, Boolean
18
+ attribute :enable_planned_mode, Boolean
19
+ attribute :enable_tasks, Boolean
20
+ attribute :epic_ids, Array[Integer]
21
+ attribute :epics, Array[TrackerApi::Resources::Epic]
22
+ attribute :has_google_domain, Boolean
23
+ attribute :id, Integer
24
+ attribute :initial_velocity, Integer
25
+ attribute :iteration_length, Integer
26
+ attribute :kind, String
27
+ attribute :label_ids, Array[Integer]
28
+ attribute :labels, Array[TrackerApi::Resources::Label]
29
+ attribute :name, String
30
+ attribute :number_of_done_iterations_to_show, Integer
31
+ attribute :point_scale, String
32
+ attribute :point_scale_is_custom, Boolean
33
+ attribute :profile_content, String
34
+ attribute :public, Boolean
35
+ attribute :start_date, DateTime
36
+ attribute :start_time, DateTime
37
+ attribute :time_zone, TrackerApi::Resources::TimeZone
38
+ attribute :updated_at, DateTime
39
+ attribute :velocity_averaged_over, Integer
40
+ attribute :version, Integer
41
+ attribute :week_start_day, String
42
+
43
+ # @return [String] comma separated list of labels
44
+ def label_list
45
+ @label_list ||= labels.collect(&:name).join(',')
46
+ end
47
+
48
+ # @param [Hash] params
49
+ # @return [Array[Epic]] epics associated with this project
50
+ def epics(params={})
51
+ raise ArgumentError, 'Expected @epics to be an Array' unless @epics.is_a? Array
52
+ return @epics unless @epics.empty?
53
+
54
+ @epics = Endpoints::Epics.new(client).get(id, params)
55
+ end
56
+
57
+ # @param [Hash] params
58
+ # @option params [String] :scope Restricts the state of iterations to return.
59
+ # If not specified, it defaults to all iterations including done.
60
+ # Valid enumeration values: done, current, backlog, current_backlog.
61
+ # @option params [Integer] :number The iteration to retrieve, starting at 1
62
+ # @option params [Integer] :offset The offset of first iteration to return, relative to the
63
+ # set of iterations specified by 'scope', with zero being the first iteration in the scope.
64
+ # @option params [Integer] :limit The number of iterations to return relative to the offset.
65
+ # @return [Array[Iteration]] iterations associated with this project
66
+ def iterations(params = {})
67
+ if params.include?(:number)
68
+ number = params[:number].to_i
69
+ raise ArgumentError, ':number must be > 0' unless number > 0
70
+
71
+ params = params.merge(auto_paginate: false, limit: 1)
72
+ params.delete(:number)
73
+
74
+ offset = number - 1
75
+ params[:offset] = offset if offset > 0
76
+ end
77
+
78
+ Endpoints::Iterations.new(client).get(id, params)
79
+ end
80
+
81
+ # @param [Hash] params
82
+ # @option params [String] :with_label A label name which all returned stories must match.
83
+ # @option params [String] :with_state A story's current_state which all returned stories must match.
84
+ # Valid enumeration values: accepted, delivered, finished, started, rejected, unstarted, unscheduled
85
+ # @option params [String] :filter This parameter supplies a search string;
86
+ # only stories that match the search criteria are returned.
87
+ # Cannot be used together with any other parameters except limit and offset.
88
+ # ex) state:started requester:OWK label:"jedi stuff" keyword
89
+ # @option params [Integer] :offset With the first story in your priority list as 0,
90
+ # the index of the first story you want returned.
91
+ # @option params [Integer] :limit The number of stories you want returned.
92
+ # @return [Array[Story]] stories associated with this project
93
+ def stories(params = {})
94
+ Endpoints::Stories.new(client).get(id, params)
95
+ end
96
+
97
+ # @param [Hash] params
98
+ # @return [Array[ProjectMembership]] memberships of this project
99
+ def memberships(params = {})
100
+ Endpoints::Memberships.new(client).get(id, params)
101
+ end
102
+
103
+ # Provides a list of all the activity performed on a project.
104
+ #
105
+ # @param [Hash] params
106
+ # @return [Array[Activity]]
107
+ def activity(params = {})
108
+ Endpoints::Activity.new(client).get_project(id, params)
109
+ end
110
+
111
+ # @param [Fixnum] story_id id of story to get
112
+ # @return [Story] story with given id
113
+ def story(story_id)
114
+ Endpoints::Story.new(client).get(id, story_id)
115
+ end
116
+
117
+ # @param [Hash] params attributes to create the story with
118
+ # @return [Story] newly created Story
119
+ def create_story(params)
120
+ Endpoints::Story.new(client).create(id, params)
121
+ end
122
+
123
+ # @file_name [String] name of the file to be uploaded. Full path to be specified
124
+ # @content_type [String] content type of the file.
125
+ # @return [FileAttachment] newly created FileAttachment.
126
+ def add_attachment(file_name, content_type)
127
+ Endpoints::FileAttachment.new(client).create(id, file_name, content_type)
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,16 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class ProjectMembership
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :person_id, Integer
8
+ attribute :project_id, Integer
9
+ attribute :role, String
10
+ attribute :project_color, String
11
+ attribute :wants_comment_notification_emails, Boolean
12
+ attribute :kind, String
13
+ attribute :person, TrackerApi::Resources::Person
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,102 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Story
4
+ include TrackerApi::Resources::Base
5
+
6
+ attribute :client
7
+
8
+ attribute :accepted_at, DateTime
9
+ attribute :comment_ids, Array[Integer]
10
+ attribute :comments, Array[TrackerApi::Resources::Comment]
11
+ attribute :created_at, DateTime
12
+ attribute :current_state, String # (accepted, delivered, finished, started, rejected, planned, unstarted, unscheduled)
13
+ attribute :deadline, DateTime
14
+ attribute :description, String
15
+ attribute :estimate, Float
16
+ attribute :external_id, String
17
+ attribute :follower_ids, Array[Integer]
18
+ attribute :integration_id, Integer
19
+ attribute :kind, String
20
+ attribute :label_ids, Array[Integer]
21
+ attribute :labels, Array[TrackerApi::Resources::Label]
22
+ attribute :name, String
23
+ attribute :owned_by_id, Integer # deprecated!
24
+ attribute :owner_ids, Array[Integer]
25
+ attribute :owners, Array[TrackerApi::Resources::Person]
26
+ attribute :planned_iteration_number, Integer
27
+ attribute :project_id, Integer
28
+ attribute :requested_by_id, Integer
29
+ attribute :story_type, String # (feature, bug, chore, release)
30
+ attribute :task_ids, Array[Integer]
31
+ attribute :tasks, Array[TrackerApi::Resources::Task]
32
+ attribute :updated_at, DateTime
33
+ attribute :url, String
34
+ attribute :before_id, Integer
35
+ attribute :after_id, Integer
36
+
37
+ # @return [String] Comma separated list of labels.
38
+ def label_list
39
+ @label_list ||= labels.collect(&:name).join(',')
40
+ end
41
+
42
+ # Provides a list of all the activity performed on the story.
43
+ #
44
+ # @param [Hash] params
45
+ # @return [Array[Activity]]
46
+ def activity(params = {})
47
+ Endpoints::Activity.new(client).get_story(project_id, id, params)
48
+ end
49
+
50
+ # Provides a list of all the comments on the story.
51
+ #
52
+ # @param [Hash] params
53
+ # @return [Array[Comment]]
54
+ def comments(params = {})
55
+ if @comments.any?
56
+ @comments
57
+ else
58
+ @comments = Endpoints::Comments.new(client).get(project_id, id, params)
59
+ end
60
+ end
61
+
62
+ # @param [Hash] params
63
+ # @return [Array[Task]]
64
+ def tasks(params = {})
65
+ if @tasks.any?
66
+ @tasks
67
+ else
68
+ @tasks = Endpoints::Tasks.new(client).get(project_id, id, params)
69
+ end
70
+ end
71
+
72
+ # Save changes to an existing Story.
73
+ def save
74
+ raise ArgumentError, 'Can not update a story with an unknown project_id.' if project_id.nil?
75
+
76
+ Endpoints::Story.new(client).update(self, just_changes)
77
+
78
+ changes_applied
79
+ end
80
+
81
+ # update labels.This method can also be used to remove labels.
82
+ def add_labels(*new_labels)
83
+ raise ArgumentError, 'Can not update a story with an unknown project_id.' if project_id.nil?
84
+ raise ArgumentError, 'Provide at lease one label name' if new_labels.empty?
85
+
86
+ Endpoints::Story.new(client).update(self, {:labels => new_labels.map{|l| {:name => l.to_s}}})
87
+
88
+ changes_applied
89
+ end
90
+
91
+ # Add an existing attachment to the story
92
+ def add_comment_with_attachment(text, file_attachment)
93
+ raise ArgumentError, 'Can not update a story with an unknown project_id.' if project_id.nil?
94
+
95
+ comment = {:text => text, :file_attachments => [file_attachment.attributes]}
96
+ Endpoints::Comments.new(client).create_with_attachment(project_id, id, text, file_attachment)
97
+
98
+ changes_applied
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,16 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class Task
4
+ include Virtus.model
5
+
6
+ attribute :id, Integer
7
+ attribute :story_id, Integer
8
+ attribute :description, String
9
+ attribute :complete, Boolean
10
+ attribute :position, Integer
11
+ attribute :created_at, DateTime
12
+ attribute :updated_at, DateTime
13
+ attribute :kind, String
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module TrackerApi
2
+ module Resources
3
+ class TimeZone
4
+ include Virtus.value_object
5
+
6
+ values do
7
+ attribute :offset, String
8
+ attribute :olson_name, String
9
+ attribute :kind, String
10
+ end
11
+ end
12
+ end
13
+ end