ki_pivotal 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/bin/ki_pivotal CHANGED
@@ -23,6 +23,10 @@ program_desc 'A Kiseru command-line interface for Pivotal Tracker'
23
23
 
24
24
  version KiPivotal::VERSION
25
25
 
26
+ desc "The project ID"
27
+ arg_name 'id'
28
+ flag [:project]
29
+
26
30
  desc 'Initialise config files'
27
31
  command :init do |c|
28
32
  c.action do |global_options,options,args|
@@ -35,7 +39,7 @@ end
35
39
  desc 'Get projects'
36
40
  command :projects do |c|
37
41
  c.action do |global_options, options, args|
38
- pretty = $stdout.tty?
42
+ pretty = true # Maybe I'm crazy, but I think we always want pretty print
39
43
  $stdout.puts KiPivotal::Api.new.projects(:pretty => pretty)
40
44
  end
41
45
  end
@@ -43,12 +47,14 @@ end
43
47
  desc 'Get stories'
44
48
  command :stories do |c|
45
49
  c.desc "The project ID"
46
- c.flag [:p, :project]
50
+ c.flag [:project]
47
51
  c.desc "Interactive mode"
48
52
  c.switch [:i, :interactive]
49
53
  c.action do |global_options, options, args|
50
54
  if options[:project]
51
55
  project_id = options[:project]
56
+ elsif global_options[:project]
57
+ project_id = global_options[:project]
52
58
  else
53
59
  if options[:i]
54
60
  project_id = KiPivotal::Interactive.select_project("Which project would you like to view the stories of?")
@@ -66,20 +72,47 @@ command :stories do |c|
66
72
  end
67
73
  end
68
74
 
69
- $stdout.puts KiPivotal::Api.new.stories_in_project(project_id, :pretty => $stdout.tty?)
75
+ $stdout.puts KiPivotal::Api.new.stories_in_project(project_id, :pretty => true)
76
+ end
77
+ end
78
+
79
+ desc 'Get members of a project'
80
+ command :members do |c|
81
+ c.desc "The project ID"
82
+ c.flag [:project]
83
+ c.desc "Interactive mode"
84
+ c.switch [:i, :interactive]
85
+ c.action do |global_options, options, args|
86
+ unless project_id = options[:project] || project_id = global_options[:project]
87
+ if options[:i]
88
+ project_id = KiPivotal::Interactive.select_project("Which project would you like to view the members of?")
89
+ else
90
+ projects = MultiJson.load(KiPivotal::Api.new.projects)
91
+ $stderr.puts "\n Members cannot be retrieved without specifying which project to retrieve from:"
92
+ $stderr.puts " * The ID of a chosen project may be specified with --project=<ID>"
93
+ $stderr.puts " * A project may be chosen interactively by using the switch -i."
94
+ $stderr.puts "\n Available projects:"
95
+
96
+ projects.each { |project| $stderr.puts " #{project['id']} ".green + " #{project['name']}" }
97
+
98
+ $stderr.puts
99
+ raise "No project given"
100
+ end
101
+ end
102
+ $stdout.puts KiPivotal::Api.new.members_of_project(project_id, :pretty => true)
70
103
  end
71
104
  end
72
105
 
73
106
  desc 'Get a story'
107
+ arg_name 'story_id'
74
108
  command :story do |c|
75
- c.desc "The story ID"
76
- c.flag :id
77
109
  c.desc "The project ID"
78
- c.flag [:p, :project]
110
+ c.arg_name 'id'
111
+ c.flag [:project]
79
112
  c.desc "Interactive mode"
80
113
  c.switch [:i, :interactive]
81
114
  c.action do |global_options, options, args|
82
- unless project_id = options[:project]
115
+ unless project_id = options[:project] || project_id = global_options[:project]
83
116
  if options[:i]
84
117
  project_id = KiPivotal::Interactive.select_project("Which project would you like to retrieve the story from?")
85
118
  else
@@ -95,7 +128,7 @@ command :story do |c|
95
128
  raise "No project given"
96
129
  end
97
130
  end
98
- unless story_id = options[:id]
131
+ unless story_id = args.first
99
132
  if options[:i]
100
133
  story_id = KiPivotal::Interactive.select_story(project_id, "Which story would you like to view?")
101
134
  else
@@ -111,7 +144,7 @@ command :story do |c|
111
144
  raise "No story ID given"
112
145
  end
113
146
  end
114
- $stdout.puts KiPivotal::Api.new.story_in_project(story_id, project_id, :pretty => $stdout.tty?)
147
+ $stdout.puts KiPivotal::Api.new.story_in_project(story_id, project_id, :pretty => true)
115
148
  end
116
149
  end
117
150
 
@@ -130,13 +163,21 @@ command :new_story do |c|
130
163
  # project ID to be specified.
131
164
  if options[:f] || !$stdin.tty?
132
165
  story_json = options[:f] ? File.read(options[:f]) : $stdin.read
133
- unless project_id = options[:project]
166
+ received_json = MultiJson.load(story_json)
167
+ if options[:i]
168
+ $stderr.puts "\nReceived the following JSON:"
169
+ $stderr.puts MultiJson.dump(received_json, :pretty => true)
170
+ $stderr.print "Do you wish to proceed? (Y/n): "
171
+ $stdin = STDIN.reopen('/dev/tty')
172
+ unless ["","y","yes"].include? $stdin.gets.chomp.downcase
173
+ raise "Aborted by user"
174
+ end
175
+ end
176
+ unless project_id = options[:project] || global_options[:project]
134
177
  # Check the json for a 'project_id' attribute for template story niceness.
135
- json = MultiJson.load(story_json)
136
- project_id = json['project_id']
178
+ project_id = received_json['project_id']
137
179
  if project_id.nil?
138
180
  if options[:i]
139
- $stdin = STDIN.reopen('/dev/tty')
140
181
  project_id = KiPivotal::Interactive.select_project("Which project should this story be created under?")
141
182
  else
142
183
  projects = MultiJson.load(KiPivotal::Api.new.projects)
data/ki_pivotal.gemspec CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency('gli', '~> 1.6.0')
19
19
  gem.add_dependency('multi_json', '~> 1.3.6')
20
+ gem.add_dependency('multi_xml', '~> 0.5.1')
20
21
  gem.add_dependency('pivotal-tracker', '~> 0.5.4')
21
22
  gem.add_dependency('colored', '~> 1.2.0')
22
23
 
@@ -47,11 +47,28 @@ module KiPivotal
47
47
  end
48
48
  end
49
49
 
50
+ def members_of_project(project_id, opts = {})
51
+ with_session do
52
+ pretty = opts.fetch(:pretty) { true }
53
+
54
+ project = get_project(project_id)
55
+
56
+ data = project.memberships.all.map do |member|
57
+ { 'name' => member.name,
58
+ 'email' => member.email,
59
+ 'intials' => member.initials,
60
+ 'role' => member.role}
61
+ end
62
+
63
+ MultiJson.dump(data, :pretty => pretty)
64
+ end
65
+ end
66
+
50
67
  def stories_in_project(project_id, opts = {})
51
68
  with_session do
52
69
  pretty = opts.fetch(:pretty) { true }
53
70
 
54
- project = PivotalTracker::Project.find(project_id)
71
+ project = get_project(project_id)
55
72
 
56
73
  data = project.stories.all.inject([]) { |array, story| array << story_to_hash(story).merge({'project_id' => project_id}) }
57
74
 
@@ -63,9 +80,15 @@ module KiPivotal
63
80
  with_session do
64
81
  pretty = opts.fetch(:pretty) { true }
65
82
 
66
- project = PivotalTracker::Project.find(project_id)
67
83
 
68
- data = story_to_hash(project.stories.find(story_id)).merge({'project_id' => project_id})
84
+
85
+ story = project.stories.find(story_id)
86
+
87
+ raise ApiError, "No story #{story_id} for project #{project_id} ('#{project.name}')" if story.nil?
88
+
89
+ data = story_to_hash(story).
90
+ merge({'project_id' => project_id}).
91
+ merge({:notes => story.notes.all.map { |n| note_to_hash(n) }})
69
92
 
70
93
  MultiJson.dump(data, :pretty => pretty)
71
94
  end
@@ -85,7 +108,7 @@ module KiPivotal
85
108
  # * convert data back into JSON
86
109
  def add_story_to_project(project_id, data)
87
110
  begin
88
- project = PivotalTracker::Project.find(project_id)
111
+ project = get_project(project_id)
89
112
  rescue RestClient::ResourceNotFound => e
90
113
  raise ApiError, "Invalid project ID #{project_id}"
91
114
  end
@@ -100,6 +123,13 @@ module KiPivotal
100
123
  end
101
124
  end
102
125
 
126
+ def note_to_hash(note)
127
+ { 'text' => note.text,
128
+ 'author' => note.author,
129
+ 'noted_at' => note.noted_at
130
+ }
131
+ end
132
+
103
133
  def story_to_hash(story)
104
134
  {'ki_type' => 'pivotal_story',
105
135
  'id' => story.id,
@@ -109,6 +139,7 @@ module KiPivotal
109
139
  'story_url' => story.url,
110
140
  'description' => story.description,
111
141
  'requested_by' => story.requested_by,
142
+ 'owned_by' => story.owned_by,
112
143
  'current_state' => story.current_state}
113
144
  end
114
145
 
@@ -130,6 +161,18 @@ module KiPivotal
130
161
  end
131
162
  end
132
163
 
164
+ def get_project(id)
165
+ begin
166
+ PivotalTracker::Project.find(id)
167
+ rescue RestClient::ResourceNotFound
168
+ raise ApiError, "No project #{id}"
169
+ rescue RestClient::BadRequest => e
170
+ data = MultiXml.parse(e.http_body)
171
+ raise ApiError, "#{data['message']}"
172
+ end
173
+ end
174
+
133
175
  end
134
176
 
177
+
135
178
  end
@@ -9,6 +9,7 @@ module KiPivotal
9
9
  def init
10
10
  @config.ensure_present('api_token')
11
11
  PivotalTracker::Client.token = @config.read('api_token')
12
+ PivotalTracker::Client.use_ssl = true
12
13
  end
13
14
 
14
15
  end
@@ -1,3 +1,3 @@
1
1
  module KiPivotal
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/ki_pivotal.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'yaml/store'
2
2
  require 'pivotal-tracker'
3
3
  require 'multi_json'
4
+ require 'multi_xml'
4
5
 
5
6
  require "ki_pivotal/version"
6
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ki_pivotal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-16 00:00:00.000000000Z
13
+ date: 2012-08-17 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gli
17
- requirement: &70289977107260 !ruby/object:Gem::Requirement
17
+ requirement: &70237509554480 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.6.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70289977107260
25
+ version_requirements: *70237509554480
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: multi_json
28
- requirement: &70289977106760 !ruby/object:Gem::Requirement
28
+ requirement: &70237509552020 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,21 @@ dependencies:
33
33
  version: 1.3.6
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70289977106760
36
+ version_requirements: *70237509552020
37
+ - !ruby/object:Gem::Dependency
38
+ name: multi_xml
39
+ requirement: &70237509551020 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 0.5.1
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *70237509551020
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: pivotal-tracker
39
- requirement: &70289977106300 !ruby/object:Gem::Requirement
50
+ requirement: &70237509538700 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ~>
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: 0.5.4
45
56
  type: :runtime
46
57
  prerelease: false
47
- version_requirements: *70289977106300
58
+ version_requirements: *70237509538700
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: colored
50
- requirement: &70289977105840 !ruby/object:Gem::Requirement
61
+ requirement: &70237509537340 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ~>
@@ -55,10 +66,10 @@ dependencies:
55
66
  version: 1.2.0
56
67
  type: :runtime
57
68
  prerelease: false
58
- version_requirements: *70289977105840
69
+ version_requirements: *70237509537340
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: debugger
61
- requirement: &70289977105380 !ruby/object:Gem::Requirement
72
+ requirement: &70237509535860 !ruby/object:Gem::Requirement
62
73
  none: false
63
74
  requirements:
64
75
  - - ~>
@@ -66,10 +77,10 @@ dependencies:
66
77
  version: 1.2.0
67
78
  type: :development
68
79
  prerelease: false
69
- version_requirements: *70289977105380
80
+ version_requirements: *70237509535860
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: rake
72
- requirement: &70289977104920 !ruby/object:Gem::Requirement
83
+ requirement: &70237509534040 !ruby/object:Gem::Requirement
73
84
  none: false
74
85
  requirements:
75
86
  - - ~>
@@ -77,10 +88,10 @@ dependencies:
77
88
  version: 0.9.2
78
89
  type: :development
79
90
  prerelease: false
80
- version_requirements: *70289977104920
91
+ version_requirements: *70237509534040
81
92
  - !ruby/object:Gem::Dependency
82
93
  name: rspec
83
- requirement: &70289977104460 !ruby/object:Gem::Requirement
94
+ requirement: &70237509532480 !ruby/object:Gem::Requirement
84
95
  none: false
85
96
  requirements:
86
97
  - - ~>
@@ -88,10 +99,10 @@ dependencies:
88
99
  version: 2.11.0
89
100
  type: :development
90
101
  prerelease: false
91
- version_requirements: *70289977104460
102
+ version_requirements: *70237509532480
92
103
  - !ruby/object:Gem::Dependency
93
104
  name: simplecov
94
- requirement: &70289977104000 !ruby/object:Gem::Requirement
105
+ requirement: &70237509531200 !ruby/object:Gem::Requirement
95
106
  none: false
96
107
  requirements:
97
108
  - - ~>
@@ -99,10 +110,10 @@ dependencies:
99
110
  version: 0.6.4
100
111
  type: :development
101
112
  prerelease: false
102
- version_requirements: *70289977104000
113
+ version_requirements: *70237509531200
103
114
  - !ruby/object:Gem::Dependency
104
115
  name: test-construct
105
- requirement: &70289977103540 !ruby/object:Gem::Requirement
116
+ requirement: &70237509516680 !ruby/object:Gem::Requirement
106
117
  none: false
107
118
  requirements:
108
119
  - - ~>
@@ -110,10 +121,10 @@ dependencies:
110
121
  version: 1.2.0
111
122
  type: :development
112
123
  prerelease: false
113
- version_requirements: *70289977103540
124
+ version_requirements: *70237509516680
114
125
  - !ruby/object:Gem::Dependency
115
126
  name: vcr
116
- requirement: &70289996128980 !ruby/object:Gem::Requirement
127
+ requirement: &70237509516080 !ruby/object:Gem::Requirement
117
128
  none: false
118
129
  requirements:
119
130
  - - ~>
@@ -121,10 +132,10 @@ dependencies:
121
132
  version: 2.2.4
122
133
  type: :development
123
134
  prerelease: false
124
- version_requirements: *70289996128980
135
+ version_requirements: *70237509516080
125
136
  - !ruby/object:Gem::Dependency
126
137
  name: webmock
127
- requirement: &70289996128520 !ruby/object:Gem::Requirement
138
+ requirement: &70237509515320 !ruby/object:Gem::Requirement
128
139
  none: false
129
140
  requirements:
130
141
  - - ~>
@@ -132,7 +143,7 @@ dependencies:
132
143
  version: 1.8.8
133
144
  type: :development
134
145
  prerelease: false
135
- version_requirements: *70289996128520
146
+ version_requirements: *70237509515320
136
147
  description: Kiseru Pivotal Tracker client
137
148
  email:
138
149
  - ben@freeagent.com
@@ -171,12 +182,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
182
  - - ! '>='
172
183
  - !ruby/object:Gem::Version
173
184
  version: '0'
185
+ segments:
186
+ - 0
187
+ hash: -4496773559274794562
174
188
  required_rubygems_version: !ruby/object:Gem::Requirement
175
189
  none: false
176
190
  requirements:
177
191
  - - ! '>='
178
192
  - !ruby/object:Gem::Version
179
193
  version: '0'
194
+ segments:
195
+ - 0
196
+ hash: -4496773559274794562
180
197
  requirements: []
181
198
  rubyforge_project:
182
199
  rubygems_version: 1.8.10