pt 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ require 'iconv' unless "older_ruby?".respond_to?(:force_encoding)
3
3
  module PT
4
4
  class DataRow
5
5
 
6
- attr_accessor :num, :record, :state
6
+ attr_accessor :num, :record, :state, :owners
7
7
 
8
8
  def initialize(orig, dataset)
9
9
  @record = orig
@@ -11,6 +11,10 @@ module PT
11
11
  if defined? orig.current_state
12
12
  @state = orig.current_state
13
13
  end
14
+
15
+ if defined? orig.owners
16
+ @owners = orig.owners.map(&:initials).join(',')
17
+ end
14
18
  end
15
19
 
16
20
  def method_missing(method)
@@ -20,6 +20,9 @@ module PT
20
20
  if config[:max_width] && config[:max_width] < max_width
21
21
  max_width = config[:max_width]
22
22
  end
23
+ headers = [:num]
24
+
25
+ headers += self.class.headers.present? ? self.class.headers : self.class.fields
23
26
 
24
27
  self.class.table @rows, :fields => [:num] + self.class.fields,
25
28
  :change_fields => %w{num pt_id},
@@ -41,6 +44,10 @@ module PT
41
44
  []
42
45
  end
43
46
 
47
+ def self.headers
48
+ []
49
+ end
50
+
44
51
  end
45
52
 
46
53
 
@@ -56,7 +63,11 @@ module PT
56
63
  class TasksTable < DataTable
57
64
 
58
65
  def self.fields
59
- [:name, :state, :id]
66
+ [:name, :owners, :story_type, :estimate, :state, :id]
67
+ end
68
+
69
+ def self.headers
70
+ [:name, :owners, :type, :point, :state, :id]
60
71
  end
61
72
 
62
73
  end
@@ -0,0 +1,271 @@
1
+ module PT
2
+ module Helper
3
+
4
+ GLOBAL_CONFIG_PATH = ENV['HOME'] + "/.pt"
5
+ LOCAL_CONFIG_PATH = Dir.pwd + '/.pt'
6
+
7
+ def load_global_config
8
+
9
+ # skip global config if env vars are set
10
+ if ENV['PIVOTAL_EMAIL'] and ENV['PIVOTAL_API_KEY']
11
+ config = {
12
+ :email => ENV['PIVOTAL_EMAIL'],
13
+ :api_number => ENV['PIVOTAL_API_KEY']
14
+ }
15
+ return config
16
+ end
17
+
18
+ config = YAML.load(File.read(GLOBAL_CONFIG_PATH)) rescue {}
19
+ if config.empty?
20
+ message "I can't find info about your Pivotal Tracker account in #{GLOBAL_CONFIG_PATH}."
21
+ while !config[:api_number] do
22
+ config[:api_number] = ask "What is your token?"
23
+ end
24
+ congrats "Thanks!",
25
+ "Your API id is " + config[:api_number],
26
+ "I'm saving it in #{GLOBAL_CONFIG_PATH} so you don't have to log in again."
27
+ save_config(config, GLOBAL_CONFIG_PATH)
28
+ end
29
+ config
30
+ end
31
+
32
+ def get_local_config_path
33
+ # If the local config path does not exist, check to see if we're in a git repo
34
+ # And if so, try the top level of the checkout
35
+ if (!File.exist?(LOCAL_CONFIG_PATH) && system('git rev-parse 2> /dev/null'))
36
+ return `git rev-parse --show-toplevel`.chomp() + '/.pt'
37
+ else
38
+ return LOCAL_CONFIG_PATH
39
+ end
40
+ end
41
+
42
+ def load_local_config
43
+ check_local_config_path
44
+ config = YAML.load(File.read(get_local_config_path())) rescue {}
45
+
46
+
47
+ if ENV['PIVOTAL_PROJECT_ID']
48
+
49
+ config[:project_id] = ENV['PIVOTAL_PROJECT_ID']
50
+
51
+ @client = Client.new(@global_config[:api_number])
52
+ project = @client.get_project(config[:project_id])
53
+ config[:project_name] = project.name
54
+
55
+ membership = @client.get_my_info
56
+ config[:user_name], config[:user_id], config[:user_initials] = membership.name, membership.id, membership.initials
57
+ save_config(config, get_local_config_path())
58
+
59
+ end
60
+
61
+ if config.empty?
62
+ message "I can't find info about this project in #{get_local_config_path()}"
63
+ @client = Client.new(@global_config[:api_number])
64
+ projects = ProjectTable.new(@client.get_projects)
65
+ project = select("Please select the project for the current directory", projects)
66
+ config[:project_id], config[:project_name] = project.id, project.name
67
+ project = @client.get_project(project.id)
68
+ membership = @client.get_my_info
69
+ config[:user_name], config[:user_id], config[:user_initials] = membership.name, membership.id, membership.initials
70
+ congrats "Thanks! I'm saving this project's info",
71
+ "in #{get_local_config_path()}: remember to .gitignore it!"
72
+ save_config(config, get_local_config_path())
73
+ end
74
+ config
75
+ end
76
+
77
+ def check_local_config_path
78
+ if GLOBAL_CONFIG_PATH == get_local_config_path()
79
+ error("Please execute .pt inside your project directory and not in your home.")
80
+ exit
81
+ end
82
+ end
83
+
84
+ def save_config(config, path)
85
+ File.new(path, 'w') unless File.exists?(path)
86
+ File.open(path, 'w') {|f| f.write(config.to_yaml) }
87
+ end
88
+
89
+ # I/O
90
+
91
+ def split_lines(text)
92
+ text.respond_to?(:join) ? text.join("\n") : text
93
+ end
94
+
95
+ def title(*msg)
96
+ puts "\n#{split_lines(msg)}".bold
97
+ end
98
+
99
+ def congrats(*msg)
100
+ puts "\n#{split_lines(msg).green.bold}"
101
+ end
102
+
103
+ def message(*msg)
104
+ puts "\n#{split_lines(msg)}"
105
+ end
106
+
107
+ def compact_message(*msg)
108
+ puts "#{split_lines(msg)}"
109
+ end
110
+
111
+ def error(*msg)
112
+ puts "\n#{split_lines(msg).red.bold}"
113
+ end
114
+
115
+ def select(msg, table)
116
+ if table.length > 0
117
+ begin
118
+ table.print @global_config
119
+ row = ask "#{msg} (1-#{table.length}, 'n' to fetch next data, 'p' to fetch previous data, 'q' to exit)"
120
+ case row
121
+ when 'q'
122
+ quit
123
+ when 'n'
124
+ return 'n'
125
+ when 'p'
126
+ return 'p'
127
+ end
128
+ selected = table[row]
129
+ error "Invalid selection, try again:" unless selected
130
+ end until selected
131
+ selected
132
+ else
133
+ table.print @global_config
134
+ message "Sorry, there are no options to select."
135
+ quit
136
+ end
137
+ end
138
+
139
+ def quit
140
+ message "bye!"
141
+ exit
142
+ end
143
+
144
+ def ask(msg)
145
+ @io.ask("#{msg.bold}")
146
+ end
147
+
148
+ def ask_secret(msg)
149
+ @io.ask("#{msg.bold}"){ |q| q.echo = '*' }
150
+ end
151
+
152
+ def user_s
153
+ "#{@local_config[:user_name]} (#{@local_config[:user_initials]})"
154
+ end
155
+
156
+ def project_to_s
157
+ "Project #{@local_config[:project_name].upcase}"
158
+ end
159
+
160
+ def task_type_or_nil query
161
+ if (["feature", "bug", "chore"].index query)
162
+ return query
163
+ end
164
+ nil
165
+ end
166
+
167
+ def task_by_id_or_pt_id id
168
+ if id < 1000
169
+ tasks = @client.get_my_work(@local_config[:user_name])
170
+ table = TasksTable.new(tasks)
171
+ table[id]
172
+ else
173
+ @client.get_task_by_id id
174
+ end
175
+ end
176
+
177
+ def find_task query
178
+ members = @client.get_members
179
+ members.each do | member |
180
+ if member.name.downcase.index query
181
+ return member.name
182
+ end
183
+ end
184
+ nil
185
+ end
186
+
187
+ def find_owner query
188
+ if query
189
+ member = @client.get_member(query)
190
+ return member ? member.person : nil
191
+ end
192
+ nil
193
+ end
194
+
195
+
196
+ def show_activity(activity, tasks)
197
+ message("#{activity.message}")
198
+ end
199
+
200
+ def get_open_story_task_from_params(task)
201
+ title "Pending tasks for '#{task.name}'"
202
+ task_struct = Struct.new(:description, :position)
203
+
204
+ pending_tasks = [
205
+ task_struct.new('<< Add new task >>', -1)
206
+ ]
207
+
208
+ task.tasks.each{ |t| pending_tasks << t unless t.complete }
209
+ table = TodoTaskTable.new(pending_tasks)
210
+ select("Pick task to edit, 1 to add new task", table)
211
+ end
212
+
213
+ def edit_story_task(task)
214
+ action_class = Struct.new(:action, :key)
215
+
216
+ table = ActionTable.new([
217
+ action_class.new('Complete', :complete),
218
+ # action_class.new('Delete', :delete),
219
+ action_class.new('Edit', :edit)
220
+ # Move?
221
+ ])
222
+ action_to_execute = select('What to do with todo?', table)
223
+
224
+ task.project_id = project.id
225
+ task.client = project.client
226
+ case action_to_execute.key
227
+ when :complete then
228
+ task.complete = true
229
+ congrats('Todo task completed!')
230
+ # when :delete then
231
+ # task.delete
232
+ # congrats('Todo task removed')
233
+ when :edit then
234
+ new_description = ask('New task description')
235
+ task.description = new_description
236
+ congrats("Todo task changed to: \"#{task.description}\"")
237
+ end
238
+ task.save
239
+ end
240
+
241
+ def save_recent_task( task_id )
242
+ # save list of recently accessed tasks
243
+ unless (@local_config[:recent_tasks])
244
+ @local_config[:recent_tasks] = Array.new();
245
+ end
246
+ @local_config[:recent_tasks].unshift( task_id )
247
+ @local_config[:recent_tasks] = @local_config[:recent_tasks].uniq()
248
+ if @local_config[:recent_tasks].length > 10
249
+ @local_config[:recent_tasks].pop()
250
+ end
251
+ save_config( @local_config, get_local_config_path() )
252
+ end
253
+
254
+ def select_story_from_paginated_table(&block)
255
+ prompt = "Please select a story"
256
+ page = 0
257
+ begin
258
+ stories = block.call(page)
259
+ table = TasksTable.new(stories)
260
+ story = select(prompt, table)
261
+ if story == 'n'
262
+ page+=1
263
+ elsif story == 'p'
264
+ page-=1
265
+ end
266
+ end while story.kind_of?(String)
267
+ story
268
+ end
269
+ end
270
+ end
271
+
@@ -1,3 +1,3 @@
1
1
  module PT
2
- VERSION = '0.8.6'
2
+ VERSION = '0.9.0'
3
3
  end
data/pt.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.summary = "Pivotal Tracker CLI (API v5)"
14
14
  spec.description = "Pivotal Tracker Command Line Interface"
15
15
  spec.executables = ["pt"]
16
-
16
+
17
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
18
  f.match(%r{^(test|spec|features)/})
19
19
  end
@@ -23,10 +23,15 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.13"
24
24
  spec.add_development_dependency "rake", "~> 10.0"
25
25
  spec.add_development_dependency "pry"
26
+ spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'aruba'
28
+ spec.add_development_dependency 'vcr'
29
+ spec.add_development_dependency 'fakeweb'
26
30
 
27
31
  spec.add_dependency 'hirb', '~> 0.7', '>= 0.7.3'
28
32
  spec.add_dependency 'hirb-unicode', '~> 0.0.5', '>= 0.0.5'
29
33
  spec.add_dependency 'colored', '~> 1.2'
30
34
  spec.add_dependency 'highline'
31
35
  spec.add_dependency 'tracker_api', '~> 1.6.0'
36
+ spec.add_dependency 'thor'
32
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.6
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Slamet Kristanto
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-02-02 00:00:00.000000000 Z
14
+ date: 2017-02-08 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -55,6 +55,62 @@ dependencies:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
57
  version: '0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: aruba
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: vcr
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: fakeweb
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
58
114
  - !ruby/object:Gem::Dependency
59
115
  name: hirb
60
116
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +193,20 @@ dependencies:
137
193
  - - "~>"
138
194
  - !ruby/object:Gem::Version
139
195
  version: 1.6.0
196
+ - !ruby/object:Gem::Dependency
197
+ name: thor
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ type: :runtime
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
140
210
  description: Pivotal Tracker Command Line Interface
141
211
  email:
142
212
  - cakmet14@gmail.com
@@ -160,12 +230,14 @@ files:
160
230
  - bin/pt
161
231
  - bin/setup
162
232
  - lib/pt.rb
233
+ - lib/pt/action.rb
234
+ - lib/pt/cli.rb
163
235
  - lib/pt/client.rb
164
236
  - lib/pt/data_row.rb
165
237
  - lib/pt/data_table.rb
166
238
  - lib/pt/debugger.rb
239
+ - lib/pt/helper.rb
167
240
  - lib/pt/switch_ssl.rb
168
- - lib/pt/ui.rb
169
241
  - lib/pt/version.rb
170
242
  - pt.gemspec
171
243
  homepage: http://www.github.com/raul/pt